Home > Blockchain >  How to redirect from domain to another domain in Next.js v13 app on server side behind proxy
How to redirect from domain to another domain in Next.js v13 app on server side behind proxy

Time:01-07

I do have many domains and I want to redirect them to one main domain.

List of domains:

  • example.com
  • example1.com
  • example2.com
  • example3.com

The main domain I want to redirect from other domains is example.com

There is a great answer to redirect Next.js on the server side to a different path.

Next.js >= 12 Now you can do redirects using middleware, create a _middleware.js file inside the pages folder (or any sub folder inside pages)

import { NextResponse, NextRequest } from 'next/server'
export async function middleware(req, ev) {
    const { pathname } = req.nextUrl
    if (pathname == '/') {
        return NextResponse.redirect('/hello-nextjs')
    }
    return NextResponse.next() } 

Source: https://stackoverflow.com/a/58182678/10826693

Note: For Next.js v13, you must create the middleware.js file in the root directory of Next.js instead of pages/_middleware.js as mentioned in that answer.

If I try to redirect to another domain, the TypeScript code in middleware.ts in the root looks like this:

/* eslint-disable @next/next/no-server-import-in-page */
import { NextResponse, NextRequest } from 'next/server'

export async function middleware(req: NextRequest) {
    const url = req.nextUrl.clone()
    console.log(url.host) //logs localhost:3000

    if (!url.host.match(/example.com/)) {
        url.host = 'example.com'
        return NextResponse.redirect(url) //never executes because the URL is always localhost in the Docker container
    }
    return NextResponse.next()
}

However, a Next.js v13 application running in a Docker container behind a proxy server always has the localhost URL in the host. And url.host in a Docker container always equals the URL localhost with a defined port inside the container (e.g. localhost:3000).

How to redirect the domains example1.com, example2.com and example3.com to example.com including the same path, query parameters and hash when I only have localhost on the server side?

CodePudding user response:

If you want to redirect all domains in the Docker container to the master domain, you need to get the redirected URL from the X-Forwarded-Host header.

In addition to the host, you must also set the correct port (80/443 - header called X-Forwarded-Port) and protocol (http/https - header called X-Forwarded-Proto).

Next.js v13 Create the middleware.ts file in the root of the app and redirect all domains that do not match the example.com domain to it in production.

/* eslint-disable @next/next/no-server-import-in-page */
import { NextRequest, NextResponse } from 'next/server';

export function middleware(request: NextRequest) {
  const url = request.nextUrl.clone();

  const isProduction = process.env.NODE_ENV === 'production' // redirect only in production
  const requestedHost = request.headers.get('X-Forwarded-Host');

  if (isProduction && requestedHost && !requestedHost.match(/example.com/)) {
    const host = `example.com`; // set your main domain

    const requestedPort = request.headers.get('X-Forwarded-Port');
    const requestedProto = request.headers.get('X-Forwarded-Proto');

    url.host = host;
    url.protocol = requestedProto || url.protocol;
    url.port = requestedPort || url.port;

    return NextResponse.redirect(url);
  }

  return NextResponse.next();
}

Now all domains example1.com, example2.com and example3.com are redirected to example.com including the same path, query parameters and hash.

  • Related