2024-10-19 Web Development

Next.js: Handling Redirects in Next.js 14+

By O. Wolfson

Currently Reading: Redirecting

Next.js provides several ways to handle redirects, each suited to different scenarios, whether they occur after an event or mutation, based on a path or condition, or for scaling a large number of redirects. Below is a brief overview of available redirect options in Next.js 14+ using the App Router.


1. redirect Function

  • Purpose: Redirects the user after a mutation or event, commonly used after actions like creating or updating content.
  • Usage: Can be used in Server Components, Server Actions, and Route Handlers.
  • Status Code: Returns a 307 (Temporary) or 303 (See Other) when used in a Server Action.
  • Example:
    tsx
    import { redirect } from 'next/navigation';
    
    export async function createPost(id: string) {
      // Create post logic
      redirect(`/post/${id}`);
    }
    

2. permanentRedirect Function

  • Purpose: Permanently redirects the user, often after a mutation or event that changes a canonical URL (e.g., updating a username).
  • Usage: Similar to redirect, used in Server Components, Server Actions, and Route Handlers.
  • Status Code: Returns a 308 (Permanent Redirect).
  • Example:
    tsx
    import { permanentRedirect } from 'next/navigation';
    
    export async function updateUsername(username: string) {
      // Update username logic
      permanentRedirect(`/profile/${username}`);
    }
    

3. useRouter Hook

  • Purpose: Client-side navigation, used in event handlers in Client Components.
  • Usage: Best suited for interactive client-side redirects.
  • Example:
    tsx
    import { useRouter } from 'next/navigation';
    
    const Page = () => {
      const router = useRouter();
      return <button onClick={() => router.push('/dashboard')}>Go to Dashboard</button>;
    };
    

4. Redirects in next.config.js

  • Purpose: Redirect incoming requests based on paths defined in the configuration. Commonly used to manage known redirects across paths or when the URL structure changes.
  • Example:
    js
    module.exports = {
      async redirects() {
        return [
          { source: '/old-path', destination: '/new-path', permanent: true },
        ];
      },
    };
    

5. NextResponse.redirect in Middleware

  • Purpose: Conditionally redirects users before the rendering process, often based on authentication or other conditions.
  • Usage: Used in Middleware to run logic before completing a request.
  • Example:
    tsx
    import { NextResponse } from 'next/server';
    
    export function middleware(req) {
      if (!authenticated) {
        return NextResponse.redirect('/login');
      }
      return NextResponse.next();
    }
    

Managing Redirects at Scale

  • For large numbers of redirects (1000+): Consider using Middleware with a custom redirect map stored in a database (like Redis) or use data lookup optimizations like a Bloom filter to efficiently handle redirects at scale.

Each method provides different levels of control over redirection, from client-side navigation to server-side responses. For complex applications with many redirects, solutions like Middleware with databases or Bloom filters can be implemented to ensure performance and scalability.