Hosting Multiple Next.js Apps with Nginx

·8 MIN READ

When you have multiple Next.js applications, sometimes you want to serve them under a single domain.
For example:

  • Main app → example.com/
  • India app → example.com/in/

This is possible using Nginx reverse proxy.


Step 1: Install Nginx

On Ubuntu/Debian:

sudo apt update
sudo apt install nginx -y

Step 2: Configure Next.js with basePath

For apps running on subdirectories (like /in/), you need to configure the basePath in next.config.js:

For the India app (running on /in/):

// next.config.js or next.config.ts
const nextConfig = {
  basePath: '/in',
  assetPrefix: '/in',
  // Optional: trailing slash handling
  trailingSlash: true,
}
 
module.exports = nextConfig

For the main app (root /):

No basePath needed - it runs on the root.

// next.config.js or next.config.ts
const nextConfig = {
  // Your normal config
}
 
module.exports = nextConfig

Step 3: Run Your Next.js Apps

Start your apps on different ports:

# App 1 (Main)
npm run start -- -p 3000
 
# App 2 (India) - with basePath configured
npm run start -- -p 3001

Step 4: Configure Nginx

Create a new file:

sudo nano /etc/nginx/sites-available/example.com

Paste this configuration:

server {
    server_name example.com;
 
    # Main app on root /
    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;
    }
 
    # India app on /in/
    location ^~ /in/ {
        proxy_pass http://localhost:3001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        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;
        proxy_cache_bypass $http_upgrade;
    }
 
    # Exact match for /in
    location = /in {
        proxy_pass http://localhost:3001/in;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
    }
 
    listen 80;
}

Step 5: Enable the Site

sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx

Step 6: Add SSL with Certbot

sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d example.com

✅ Done!

Now:

  • example.com → serves your main app.
  • example.com/in → serves your India app.

This setup is simple and scalable — you can add more apps by mapping different paths.


Why basePath is Important

When you set basePath: '/in' in Next.js:

  • All routes automatically get the /in prefix
  • Links like <Link href="/about"> become /in/about
  • Static assets are served from /in/_next/...
  • API routes work correctly: /api/users/in/api/users

Without basePath, your app would try to load assets from the root, causing 404 errors.


Extra Tip

Instead of /in/, you can also use subdomains (like in.example.com). That's often cleaner for multi-region apps, and you won't need basePath configuration.