July 7, 2024

Md. Saad

A redirect is a way to send users and search engines to a URL different from the one originally requested. In other words, you redirect the user or search engine from one URL to another.
In Next.js, redirects are configured in the next.config.js file using the redirects function. This allows you to define URL redirects with status codes for client and server-side routing, enhancing SEO and ensuring users effortlessly reach the correct content.
To use redirects in Next.js, you need to define them in the next.config.js file. Here is a step-by-step guide:
source: The incoming request path pattern.
destination: The path you want to route to.
permanent: A boolean indicating the type of redirect. If true, it uses a 308 status code (permanent redirect, cached). It uses a 307 status code (temporary redirect, not cached) if false.
module.exports = {
async redirects() {
return [
{
source: '/old-page', // The old URL
destination: '/new-page', // The new URL
permanent: true, // This will trigger a 301 redirect
},
{
source: '/temporary-page',
destination: '/new-temporary-page',
permanent: false, // This will trigger a 302 redirect
},
// Add more redirects as needed
]
},
}In this example:
Apart from these source, destination, and permanent properties, you may need to include some other properties such as basePath, locale, has, and missing in redirects. Let’s Discuss these in detail also:
module.exports = {
basePath: '/docs',
async redirects() {
return [
{
source: '/with-basePath', // automatically becomes /docs/with-basePath
destination: '/another', // automatically becomes /docs/another
permanent: false,
},
{
// does not add /docs since basePath: false is set
source: '/without-basePath',
destination: 'https://example.com',
basePath: false,
permanent: false,
},
]
},
}Note:
Next.js redirect support path matching as well as wildcard path matching. For example, /old-blog/:slug will match /old-blog/hello-world.
module.exports = {
async redirects() {
return [
{
source: '/blog/:slug',
destination: '/news/:slug', // Matched parameters can be used in the destination
permanent: true,
},
]
},
}However, This will not match nested paths. To solve this problem we can use wildcard path matching. To match a nested path use after a parameter. For Example, /blog/:slug will match all the nested paths inside the blog folder such as /blog/a/b/c/d/hello-world:
module.exports = {
async redirects() {
return [
{
source: '/blog/:slug*',
destination: '/news/:slug*', // Matched parameters can be used in the destination
permanent: true,
},
]
},
}Furthermore, we can also match the path using regex. To use a regex path matching, we have to wrap the regex in parentheses after a parameter, for example, /post/:slug(\\d{1,}) will match /post/123 but not /post/abc.
module.exports = {
async redirects() {
return [
{
source: '/post/:slug(\\d{1,})',
destination: '/news/:slug', // Matched parameters can be used in the destination
permanent: false,
},
]
},
}(, ), {, }, :, *, +, ? are used for regex. So, when these characters are used as non-special values, we must have to add a \\ before them to be escaped. An example is given below:
module.exports = {
async redirects() {
return [
{
// this will match `/english(default)/something` being requested
source: '/english\\(default\\)/:slug',
destination: '/en-us/:slug',
permanent: false,
},
]
},
}In Next.js, we can create dynamic redirects that use header, cookie, and query parameter matching to redirect users conditionally. This allows you to tailor the redirect behaviour based on the presence or absence of specific headers, cookies, or query parameters.
To initiate a redirect based on header, cookie, or query matches, use the has and missing fields. The redirect applies only if all has conditions match and all missing conditions do not.
The has and missing items can have the following fields:
module.exports = {
async redirects() {
return [
// if the header `x-redirect-me` is present,
// this redirect will be applied
{
source: '/:path((?!another-page$).*)',
has: [
{
type: 'header',
key: 'x-redirect-me',
},
],
permanent: false,
destination: '/another-page',
},
// if the header `x-dont-redirect` is present,
// this redirect will NOT be applied
{
source: '/:path((?!another-page$).*)',
missing: [
{
type: 'header',
key: 'x-do-not-redirect',
},
],
permanent: false,
destination: '/another-page',
},
// if the source, query, and cookie are matched,
// this redirect will be applied
{
source: '/specific/:path*',
has: [
{
type: 'query',
key: 'page',
// the page value will not be available in the
// destination since value is provided and doesn't
// use a named capture group e.g. (?<page>home)
value: 'home',
},
{
type: 'cookie',
key: 'authorized',
value: 'true',
},
],
permanent: false,
destination: '/another/:path*',
},
// if the header `x-authorized` is present and
// contains a matching value, this redirect will be applied
{
source: '/',
has: [
{
type: 'header',
key: 'x-authorized',
value: '(?<authorized>yes|true)',
},
],
permanent: false,
destination: '/home?authorized=:authorized',
},
// if the host is `example.com`,
// this redirect will be applied
{
source: '/:path((?!another-page$).*)',
has: [
{
type: 'host',
value: 'example.com',
},
],
permanent: false,
destination: '/another-page',
},
]
},
}Next.js Redirects also supports i18n. By default, each source and destination is automatically prefixed with locales. To disable this, we need to set locale: false in the redirect configuration and manually prefix the source and destination for correct matching. This ensures accurate handling of multilingual redirects. An example is given below:
module.exports = {
i18n: {
locales: ['en', 'fr', 'de'],
defaultLocale: 'en',
},
async redirects() {
return [
{
source: '/with-locale', // automatically handles all locales
destination: '/another', // automatically passes the locale on
permanent: false,
},
{
// does not handle locales automatically since locale: false is set
source: '/nl/with-locale-manual',
destination: '/nl/another',
locale: false,
permanent: false,
},
{
// this matches '/' since `en` is the defaultLocale
source: '/en',
destination: '/en/another',
locale: false,
permanent: false,
},
// it's possible to match all locales even when locale: false is set
{
source: '/:locale/page',
destination: '/en/newpage',
permanent: false,
locale: false,
},
{
// this gets converted to /(en|fr|de)/(.*) so will not match the top-level
// `/` or `/fr` routes like /:path* would
source: '/(.*)',
destination: '/another',
permanent: false,
},
]
},
}That’s all. For more information, you can visit the official next.js page here.
Finally, Next.js redirects efficiently manage URL changes, SEO, and user experience. By leveraging options like basePath, locale, and conditional matching (has, missing), you can create precise, dynamic redirects that maintain request methods and cater to specific contexts, enhancing site functionality and navigation.
Want to add redirects to your existing site? Contact StaticMania. Our dedicated team will help you every step of the way to handle redirects in Next.js.