4

How can I set up all requests to http://example.com to be redirected to https://example.com within a Next.js app?

Haven't rly worked with Next.js much. Coming from backend side. I'm looking for a file that initializes the Next.js server, but can't seem to find one. The closest I come to is /src/pages/_app.tsx.

I found this answer addressing the same issue, but there's no place in my project where I have access to req or res objects. The app is started simply with next start.

The official docs have info on redirecting separate endpoints, but I'd like to achieve that as a default config for all endpoints.

Milkncookiez
  • 6,817
  • 10
  • 57
  • 96
  • 1
    In my case, we use an Express custom server. So we use middleware to handle it. You can probably handle it in nginx or something like that. – Andrew Zheng Aug 04 '21 at 13:55

3 Answers3

1

Since Next.js v12, there is something called "middleware". It is a unique file that acts as a middleware between the server and the client. Here is my implementation in TypeScript:

import { NextRequest, NextResponse } from "next/server";

type Environment = "production" | "development" | "other";

export function middleware(request: NextRequest) {
  const currentEnv = process.env.NODE_ENV as Environment;
  const isLocalhost = request.headers.get("host")?.includes("localhost");
  const isProtocolHTTP = request.headers.get("x-forwarded-proto") === "http";

  if (currentEnv === "production" && !isLocalhost && isProtocolHTTP) {
    return NextResponse.redirect(
      `https://${request.headers.get("host")}${request.nextUrl.pathname}${
        request?.nextUrl?.search || ""
      }`,
      301,
    );
  }
}

export const config = {
  matcher: ["/*"],
};

For Next.js 13, we will need to use this code:

import { NextRequest, NextResponse } from "next/server";

type Environment = "production" | "development" | "other";

export function middleware(request: NextRequest) {
  const headers = new Headers(request.headers);

  const currentEnv = process.env.NODE_ENV as Environment;
  const isHttps = headers.get("x-forwarded-proto")?.split(",")[0] === "https";
  const isLocalhost = request.headers.get("host")?.includes("localhost");

  if (currentEnv === "production" && !isHttps && !isLocalhost) {
    const newUrl = new URL(`http://${headers.get("host")}` || "");
    newUrl.protocol = "https:";
    return NextResponse.redirect(newUrl.href, 301);
  }
}

Create a new file named "middleware.ts" in the root path, then all the magic will happen automatically.

I think the code speaks by itself, but here is a short explanation: We check if the environment is production, if we're not on localhost and if the protocol is HTTP. If it is, we redirect the user to the same URL without the HTTP, then we add the HTTPs to the URL.

This works perfectly and I use it in a lot of projects, also in Heroku.

Or Nakash
  • 1,345
  • 1
  • 9
  • 22
0

For me, I personally don't do redirects on the Next.JS side. Instead, I do redirects on the DNS side, using something like Cloudflare. However, if you really want to do redirects on the next.js app, Heroku redirect Next.js React client app http to https would be a good start.

Jiwu Jang
  • 28
  • 4
0
  • I'm usig the below codes for url redirection for SEO in next js.

  • At first make a file in the root called next.config.js and just copy past the below code and change the url according to your necessary.

         const urlItems = [
       {
         id: 1,
         old_url: "category/mirror-polish",
         new_url: "category/mirror-polish-124",
         status: 308,
       },
       {
         id: 2,
         old_url: "category/nano-crystal",
         new_url: "category/nano-crystal-125",
         status: 307, //temporary redirection
       },
    
       {
         id: 3,
         old_url: "/about",
         new_url: "/",
         status: 308,//premanent
       },
     ];
    
           module.exports = {
                reactStrictMode: true,
                   redirects() {
                        return urlItems.map((item) => {
                    return {
                        source: `/${item.old_url}`,
                        destination: `/${item.new_url}`,
                        permanent: item.status === 308 ? true : false,
                     };
                  });
                },
             };
    
  • When you are fetching URL data using fetch then use the below codes

       module.exports = {
          reactStrictMode: true,
          redirects: async () => {
          const result = await fetch("//api end point here");
          const urlItems = await result.json();
          return urlItems.map((item) => {
            return {
                   source: `/${item.old_url}`,
                   destination: `/${item.new_url}`,
                   permanent: item.status === 308 ? true : false,
                 };
               });
              },
        };
    
  • true will be used 308 that's permanent and false will use 307 code for temporary redirections.

  • for more info please visit https://nextjs.org/docs/api-reference/next.config.js/redirects