How to have dynamic redirect URLs in Next.js?

Viewed 341

I'm working on a Next.js/Django project, which the user is able to add some redirect logic from the admin panel like:

[       
   { source: "/about", destination: "google.com" },    
   { source: "/about1", destination: "google1.com" },    
   { source: "/about2", destination: "google2.com" },    
]

and the web application should be able to handle these dynamic redirects.

As the Nextjs docs says, we can do this in next.config.js. The problem is that we can't have dynamic data in next.config.js. With every change in this file, server must be restarted.

Here we need a logic that gets the urls using an API on website load, loops through them and listens for every route calls to see if they match the redirect data or not.

I have tried some other ways too, like trying to use useEffect, but this way causes the website to render 404 page first and then it redirects to the desired url, which is not that nice for user experience viewpoints.

1 Answers

You can use Next.js Middleware to fetch the dynamic redirects array from the API, and add your own logic to handle the redirection.

Unlike redirects in the next.config.js that run at build time, Next.js Middleware runs on each incoming request to your pages and is able to dynamically fetch the redirects every time.

export async function middleware(req) {
    // Fetch redirects array from API
    const res = await fetch('https://example.com/api/redirects');
    const redirects = await res.json();
    /* Assuming the returned `redirects` array would have the following structure:
      [
        { source: '/about-us', destination: '/about' },
        { source: '/google', destination: 'https://google.com' }
      ]
    */

    // Find the matching redirect object
    const redirect = redirects.find((redirect) => req.nextUrl.pathname === redirect.source);

    if (redirect) {
        if (redirect.destination.startsWith('http')) {
            // Handle external URL redirects
            return NextResponse.redirect(new URL(redirect.destination));
        }
        // Handle internal URL redirects
        return NextResponse.redirect(new URL(redirect.destination, req.url));
    }
    
    // Continue if no matching redirect is found
    return NextResponse.next();
}
Related