DEV Community

whchi
whchi

Posted on

3

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

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (0)

AWS GenAI LIVE!

GenAI LIVE! is a dynamic live-streamed show exploring how AWS and our partners are helping organizations unlock real value with generative AI.

Tune in to the full event

DEV is partnering to bring live events to the community. Join us or dismiss this billboard if you're not interested. ❤️