Mastering Redirection in Next.js: A Complete Guide

Redirection is a crucial element in web development, facilitating smooth navigation and enhancing user experiences. Next.js, a popular React framework, provides several powerful techniques for implementing efficient redirection. This comprehensive guide will empower you with the knowledge and skills needed to master redirection in Next.js for various scenarios.

Update: Next.js >= 13 with AppDir Enabled

For Next.js versions 13 and above, equipped with the AppDir feature, you can leverage the next/navigation library for redirection. Here are examples demonstrating its usage:

In Pages:

import { redirect } from 'next/navigation';

export default async function Home({ params }) {
    redirect('/hello-nextjs');
    // ...
}

In Client Components:

'use client';
import { useEffect } from 'react';
import { useRouter } from 'next/navigation';

export const Home = () => {
  const { push } = useRouter();

  useEffect(() => {
     push('/hello-nextjs');
  }, []);
  return <p></p>;
};

Update: Next.js >= 12.1

Starting from Next.js version 12.1, relative URLs in redirects are no longer supported and will result in errors. To manage redirection efficiently:

  1. Create a middleware.ts (or .js) file at the same level as your pages directory.

  2. Export a middleware function.

  3. Create an absolute URL and utilize the redirect function.

Here’s a TypeScript example of middleware.ts:

import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {   
  const url = request.nextUrl.clone();   
  if (url.pathname === '/') {
    url.pathname = '/hello-nextjs';
    return NextResponse.redirect(url);
  } 
}

Update: Next.js >= 12

For Next.js versions 12 and above, you can implement server-side redirects using the getServerSideProps function:

export async function getServerSideProps(context) {
  const res = await fetch(`https://.../data`);
  const data = await res.json();
  
  if (!data) {
    return {
      redirect: {
        destination: '/hello-nextjs',
        permanent: false,
      },
    };
  }

  return {
    props: {}, // will be passed to the page component as props
  };
}

Client-Side Redirects

Client-side redirection can be achieved with Next.js’s Router:

import Router from 'next/router';

componentDidMount() {
    const { pathname } = Router;
    if (pathname === '/') {
       Router.push('/hello-nextjs');
    }
}

Or using Hooks:

import React, { useEffect } from "react";
import Router from 'next/router';

useEffect(() => {
   const { pathname } = Router;
   if (pathname === '/') {
       Router.push('/hello-nextjs');
   }
 });

For a smoother redirect without flashing, consider this approach:

import React, { useEffect, useState } from "react";
import Router from 'next/router';

const MyPage = () => {
    const [loaded, setLoaded] = useState(false);

    useEffect(() => {
        const { pathname } = Router;
        // Conditional redirect
        if (pathname === '/') {
            // Using router.push may add the page to history, to prevent this:
            // Router.push('/hello-nextjs')
            location.replace('/hello-nextjs');
        } else {
            setLoaded(true);
        }
    }, []);

    if (!loaded) {
        return <div></div>; // Display nothing or a loader
    }

    return ( 
        <p>
            You will see this page only if pathname !== "/", <br/>
        </p> 
    );
}

export default MyPage;

While client-side redirection is handy, it’s advisable to handle redirects at the server level or utilize conditional component rendering for a more elegant solution.

For reference, you can explore a repository containing all the examples discussed in this article here.