Next.js Redirects
Redirects are an essential part of modern web applications. They help you guide users from one URL to another, handle deprecated routes, and maintain SEO when your site structure changes. In this guide, we'll explore how Next.js handles redirects and how you can implement them effectively in your applications.
Introduction to Redirects in Next.js
In web development, a redirect is a way to forward users from one URL to another. Next.js provides multiple ways to implement redirects:
- Configuration-based redirects in
next.config.js
- Runtime redirects using the Next.js API
- Middleware redirects for more complex logic
Redirects are useful for:
- Moving pages to new URLs while ensuring users find the content
- Creating short, friendly URLs that point to longer ones
- Setting up marketing campaigns with tracking parameters
- Handling deprecated routes or migrating from an old site structure
Configuration-based Redirects
The simplest way to implement redirects in Next.js is through the next.config.js
file using the redirects
function.
Basic Redirect Example
Here's how to set up a simple redirect:
// next.config.js
module.exports = {
async redirects() {
return [
{
source: '/old-blog/:slug',
destination: '/blog/:slug',
permanent: true,
},
];
},
};
In this example:
source
: The incoming request path patterndestination
: Where the route should redirect topermanent
: Whether the redirect is permanent (true
for 308 status code) or temporary (false
for 307 status code)
When a user visits /old-blog/my-first-post
, they will be automatically redirected to /blog/my-first-post
.
Redirects with Path Parameters
You can use path parameters in both source and destination:
// next.config.js
module.exports = {
async redirects() {
return [
{
source: '/products/:category/:id',
destination: '/items/:category/:id',
permanent: false,
},
];
},
};
Redirects with Query Parameters
You can also capture and pass query parameters:
// next.config.js
module.exports = {
async redirects() {
return [
{
source: '/search',
destination: '/find',
permanent: false,
},
{
// This preserves query parameters from the source to the destination
source: '/old-search/:path*',
destination: '/new-search/:path*',
permanent: false,
},
];
},
};
Using Regular Expressions in Redirects
For more complex matching patterns, you can use regex in your redirects:
// next.config.js
module.exports = {
async redirects() {
return [
{
source: '/blog/:slug(\\d{1,})', // Only match numeric slugs
destination: '/posts/:slug',
permanent: true,
},
];
},
};
Runtime Redirects
Sometimes you need to perform redirects based on dynamic conditions during request time. Next.js provides ways to handle this in different contexts.
Redirecting in getServerSideProps
For server-rendered pages, you can redirect from within getServerSideProps
:
// pages/dashboard.js
export async function getServerSideProps(context) {
const { req, res } = context;
const userIsLoggedIn = checkUserAuthentication(req);
if (!userIsLoggedIn) {
return {
redirect: {
destination: '/login',
permanent: false,
},
};
}
return {
props: { user: getUserData(req) },
};
}
export default function Dashboard({ user }) {
return <div>Welcome, {user.name}!</div>;
}
Redirecting in getStaticProps
For statically generated pages, you can use redirects in getStaticProps
:
// pages/product/[id].js
export async function getStaticProps({ params }) {
const product = await getProduct(params.id);
if (!product) {
return {
redirect: {
destination: '/products',
permanent: false,
},
};
}
return {
props: { product },
};
}
export async function getStaticPaths() {
// ...
}
export default function Product({ product }) {
return <div>Product: {product.name}</div>;
}
Redirecting Using the Router
For client-side redirects, you can use the Next.js router:
// pages/old-feature.js
import { useEffect } from 'react';
import { useRouter } from 'next/router';
export default function OldFeaturePage() {
const router = useRouter();
useEffect(() => {
router.replace('/new-feature');
}, []);
return <p>Redirecting...</p>;
}
Middleware Redirects
Next.js 12 introduced Middleware, which provides more powerful ways to implement redirects based on complex logic:
// middleware.js
import { NextResponse } from 'next/server';
export function middleware(request) {
// Check if the user is visiting a specific country site
const country = request.geo?.country || 'US';
const { pathname } = request.nextUrl;
// Redirect users from certain countries to localized versions
if (country === 'GB' && !pathname.startsWith('/uk')) {
return NextResponse.redirect(new URL(`/uk${pathname}`, request.url));
}
return NextResponse.next();
}
export const config = {
matcher: '/((?!api|_next/static|favicon.ico).*)',
};
This middleware redirects UK visitors to the /uk
version of any page they visit.
Practical Applications
SEO-Friendly URL Structure Changes
When you decide to improve your URL structure, it's important to redirect old URLs to new ones:
// next.config.js
module.exports = {
async redirects() {
return [
// Redirect individual pages
{
source: '/info',
destination: '/about',
permanent: true,
},
// Redirect entire sections
{
source: '/articles/:slug',
destination: '/blog/:slug',
permanent: true,
},
];
},
};
Authentication Redirects
A common pattern is redirecting unauthenticated users:
// pages/profile.js
import { useSession } from 'next-auth/react';
import { useEffect } from 'react';
import { useRouter } from 'next/router';
export default function ProfilePage() {
const { data: session, status } = useSession();
const router = useRouter();
useEffect(() => {
if (status === 'unauthenticated') {
router.push(`/login?returnUrl=${encodeURIComponent(router.asPath)}`);
}
}, [status]);
if (status === 'loading') {
return <div>Loading...</div>;
}
if (!session) {
return <div>Redirecting to login...</div>;
}
return <div>Welcome to your profile, {session.user.name}!</div>;
}
Feature Flags and A/B Testing
Redirects can be used for feature rollouts and testing:
// middleware.js
import { NextResponse } from 'next/server';
export function middleware(request) {
const { nextUrl, cookies } = request;
// Check if user is in a test group
const testGroup = cookies.get('ab-test-group')?.value;
if (nextUrl.pathname === '/checkout' && testGroup === 'new-flow') {
return NextResponse.redirect(new URL('/checkout-v2', request.url));
}
return NextResponse.next();
}
export const config = {
matcher: '/checkout',
};
Managing Redirect Status Codes
The HTTP status code used for redirects matters:
-
307 (Temporary Redirect): Use when the redirect is temporary (
permanent: false
)- Search engines will keep the old URL indexed
- Used for temporary maintenance, A/B testing, etc.
-
308 (Permanent Redirect): Use when the redirect is permanent (
permanent: true
)- Search engines will update their index to the new URL
- Used for site restructuring, domain changes, etc.
Best Practices
-
Use permanent redirects wisely: Only use permanent redirects when you're certain the original URL will never be used again.
-
Minimize redirect chains: Don't redirect A → B → C. Instead, redirect A → C directly.
-
Preserve query parameters: When applicable, make sure query parameters are passed from the source to the destination.
-
Test your redirects: Always test redirects to ensure they work as expected.
-
Document your redirects: Keep track of your redirects, especially for SEO purposes.
Summary
Next.js offers multiple ways to implement redirects, from simple configuration-based approaches to dynamic, logic-driven redirects using middleware. The best approach depends on your specific use case:
- Configuration redirects are perfect for static, predictable URL changes
- Runtime redirects work well for user-specific or condition-based redirects
- Middleware redirects provide powerful capabilities for complex redirect logic
By mastering these techniques, you can ensure smooth navigation for users, maintain SEO value, and create a more robust web application.
Additional Resources
- Official Next.js Redirects Documentation
- Next.js Middleware Documentation
- Google's Guidelines on URL Redirects
Exercises
-
Implement a redirect system that sends mobile users to a mobile-specific version of your site using middleware.
-
Create a redirect system for an e-commerce site that handles legacy product URLs.
-
Build a URL shortener that uses Next.js redirects to forward users from short URLs to full destinations.
-
Implement a language-based redirect system that detects the user's browser language and redirects them to the appropriate localized version of your site.
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)