i couldn't redirect domain names to a specific page in my nextjs app using nginx.
i have a nextjs app running on localhost:3000 i used nginx for domain names redirection when i point a domain name to '/' everything works fine, but when i point a domain to '/demo' i get errors in the console indicating that static files couldn't load ! the idea that i got is to associate a domain name to each dynamic page created under '/[user-website-name]' to achieve a multi sites solution. how can i achieve this using nginx or should i modify the next.config.js file ?
my nginx conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
# HTTPS servers
server {
listen 443 ssl;
server_name domain.com www.domain.com;
ssl_certificate www.domain.com.crt;
ssl_certificate_key www.domain.com_key.txt;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
server {
listen 443 ssl;
server_name domain.com www.domain.com;
ssl_certificate www.user-created-domain.com.crt;
ssl_certificate_key www.user-created-domain.com_key.txt;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://localhost:3000/user-created-website-name;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
}
next.config.js
const path = require("path");
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
swcMinify: true,
sassOptions: {
includePaths: [path.join(__dirname, "styles")],
},
};
module.exports = nextConfig;
I solved the problem in the following steps. first all domain names should point to root:
# HTTPS servers
server {
listen 443 ssl;
server_name domain.com www.domain.com;
ssl_certificate www.domain.com.crt;
ssl_certificate_key www.domain.com_key.txt;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
server {
listen 443 ssl;
server_name user-created-domain.com www.user-created-domain.com;
ssl_certificate www.user-created-domain.com.crt;
ssl_certificate_key www.user-created-domain.com_key.txt;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Then we should use nextjs middleware and create middleware.js file in root of nextjs application.
import { NextResponse } from "next/server";
export async function middleware(request) {
const { pathname } = request.nextUrl;
const hostname = request.headers.get("host");
const url = new URL(request.url);
const domainsJsonUrl = `${url.origin}/domainNames/domainNames.json`;
let basePath = "";
// READ DOMAIN NAME FILE
const domains = await (await fetch(domainsJsonUrl)).json();
// DOMAIN NAMES SECTION
domains.forEach((_) => {
if (hostname === _.domain || hostname === `www.${_.domain}`) {
basePath = `/${_.shop}`;
}
});
// URL REWRITE SECTION
if (basePath && !pathname.startsWith(basePath)) {
const newurl = new URL(`${basePath}${pathname}`, request.url);
return NextResponse.rewrite(newurl);
}
return NextResponse.next();
}
export const config = {
matcher: [
"/((?!api|_next/static|_next/image|favicon.ico|images|manifests).*)",
],
};
so the idea that the middleware runs and checks if the host name is one of the domains that we want to redirect and then rewrite the url with new basepath so the result is transform this "www.domain.com/variant/home" to "www.domain.com/home", it is like hiding the "variant" level in the url.