Hi all,
I’m building a linktree style website hosted on example.com
. Each user profile is accessible via a path like example.com/username
.
I’d like to extend the functionality so that subdomains automatically map to their corresponding profile path. For example:
https://john.example.com/
→ should internally route to → https://example.com/john
In other words, I want NGINX to rewrite all non-reserved subdomains to /username/...
, while ignoring a whitelist of reserved subdomains like:
dashboard.example.com
api.example.com
admin.example.com
Example Behavior:
Request URL |
Should: |
https://john.example.com/ |
display → /john |
https://dashboard.example.com/ |
redirect → https://example.com/dashboard |
https://admin.example.com |
redirect → https://example.com |
Has anyone implemented something similar? I’m especially looking for:
- Clean rewrite logic
- Avoiding infinite rewrite loops
- Reserved subdomain whitelist best practices
Also I must add the fact that example.com
is behind a proxy_pass (Next.js project).
Thanks in advance!
1 Like
Dylen
2
You should be able to achieve this in NGINX using a combination of map, server_name, and rewrite directives.
Reference:
General approach:
-
Define a map for reserved subdomains (whitelist).
-
Match all subdomains using a wildcard server block.
-
Rewrite requests for non-reserved subdomains to “username”.
Dylen
3
Apologies, I missed the last bit about the proxy. For this ensure that the rewritten URL is passed correctly to your Next.js backend.
Refrence:
I tried doing that but it doesn’t work at all.
Dylen
5
Are you comfortable sharing a sanitized version of your current configs?
Hold on a second, because I am still trying to figure it out, will post in couple of mins.
1 Like
Dylen
7
If you have specific questions as your working the problem shoot them our way and we will do our best to help.
By the way hats off to your approach, I also like to noodle out a problem before I look for assistance, best way to learn IMO.
I think i did it
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
map $host $is_whitelisted {
default 0;
dashboard.example.com 1;
rules.example.com 1;
}
# Main domain
server {
listen 443 ssl;
server_name example.com;
ssl_certificate C:/nginx/_wildcard.example.com+3.pem;
ssl_certificate_key C:/nginx/_wildcard.example.com+3-key.pem;
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
# Wildcard subdomains
server {
listen 443 ssl;
server_name ~^(?<subdomain>.+)\.example\.com$;
ssl_certificate C:/nginx/_wildcard.example.com+3.pem;
ssl_certificate_key C:/nginx/_wildcard.example.com+3-key.pem;
# Redirect whitelisted subdomains to example.com
if ($is_whitelisted = 1) {
return 301 https://example.com;
}
location / {
set $target_path /$subdomain;
proxy_pass http://localhost:3000$target_path;
proxy_set_header Host example.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
# Redirect HTTP to HTTPS
server {
listen 80;
server_name example.com *.example.com;
return 301 https://$host$request_uri;
}
}
is this fine?
or do you have any other suggestions?
2 Likes
Dylen
9
Looking good, at this juncture only a couple of suggestions I think will be useful to you.
You might consider:
-
Using map and return directives at the server level, if possible, instead of the if directive, this can be more reliable.
-
Adding proxy timeout settings to avoid connection hanging.
proxy_read_timeout
proxy_connect_timeout
proxy_send_timeout