DEV Community

whchi
whchi

Posted on

Nginx setup for Next.js subdomain routing

Don't do it unless you can 100% control your nginx

In this article, I will guide you through the process of setting up Nginx(only) for subdomain routing to a Next.js router. To illustrate this, I'll use a page router as an example.

Here's a sample page router structure:

pages/
├──subdomain-1/
│           ├──index.tsx
│           └──blogs/
└──subdomain-2/
            ├──index.tsx
            └──orders/
Enter fullscreen mode Exit fullscreen mode

The expect behavior is

  1. subdomain-1.com -> /pages/subdomain-1/index.tsx
  2. subdomain-1.com/blogs -> /pages/subdomain-1/blogs/index.tsx
  3. subdomain-2.com/orders -> /pages/subdomain-2/orders/index.tsx

nginx.conf

The idea is simple, use server_name to setup 2 virtual hosts and proxy_pass proxy to the backend

http {
    upstream nextjs {
        http://localhost:3000;
    }
    server {
        listen 80;
        server_name subdomain-1.com;

        location / {
            # for i18n
            set $locale_prefix '/subdomain-1';
            set $rest $request_uri;
            if ($request_uri ~ ^/(en|ja|zh-TW)(.*)$) {
                set $locale_prefix '/$1/subdomain-1';
                set $rest $2;
            }
            proxy_pass http://nextjs$locale_prefix$rest;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }

    server {
        listen 80;
        server_name subdomain-2;
        location / {
          set $locale_prefix '/subdomain-2';
          set $rest $request_uri;
          if ($request_uri ~ ^/(en|ja|zh-TW)(.*)$) {
              set $locale_prefix '/$1/subdomain-2';
              set $rest $2;
          }
          proxy_pass http://nextjs$locale_prefix$rest;
          proxy_set_header Host $host;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header X-Forwarded-Proto $scheme;
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

next.js

you need to replace your paths in code, use router.push('/blogs') instead of router.push('/domain-2/blogs') and separate the local and production environment's behavior.

// @ts-nocheck
export const setPath = (path: string): string => {
  const PATH_PREFIXES = ['/subdomain-1', '/subdomain-2'];
  if (process.env.NODE_ENV !== 'development') {
    for (const prefix of PATH_PREFIXES) {
      if (path.startsWith(prefix)) {
        return path.slice(prefix.length);
      }
    }
  }
  return path;
};

router.push(setPath('/subdomain-1/blogs'));
Enter fullscreen mode Exit fullscreen mode

pros and cons

  • pros
    • microservices alignment
    • deployment specific subdomain won't affect your application
    • tls are managed by nginx, you can support different level of subdomain
    • cleaner code structure, each folder points to a subdomain
  • cons
    • development and deployment are more complex
    • difficult to maintain, next.js folder will be constrained by nginx config
    • initial setup is difficult, frontends need to know about nginx config

Typically, in Next.js, you should use middleware for subdomain routing.

Don't do it unless you can 100% control your nginx

Top comments (0)