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?
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 your app's src
folder 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();
}
export const config = {
matcher: '/',
};
Now all domains example1.com
, example2.com
and example3.com
are redirected to example.com
including the same path, query parameters and hash.