javascript
37 lines · 7 steps
How redirects work in Next.js config
A Next.js config builds a redirect table by combining a data-driven list with hand-written rules that use path params, query conditions, and regex.
Explained by
highlit
1const legacyRedirects = [
2 { from: '/blog/:slug', to: '/articles/:slug' },
3 { from: '/shop/product/:id', to: '/store/items/:id' },
4 { from: '/about-us', to: '/about' },
5 { from: '/help/faq', to: '/support/faq' },
6];
7
8/** @type {import('next').NextConfig} */
9const nextConfig = {
10 async redirects() {
11 return [
12 ...legacyRedirects.map(({ from, to }) => ({
13 source: from,
14 destination: to,
15 permanent: true,
16 })),
17 {
18 source: '/docs/:path*',
19 destination: 'https://docs.example.com/:path*',
20 permanent: true,
21 },
22 {
23 source: '/user/:id/profile',
24 has: [{ type: 'query', key: 'legacy', value: 'true' }],
25 destination: '/accounts/:id',
26 permanent: true,
27 },
28 {
29 source: '/:locale(en|de|fr)/news/:slug',
30 destination: '/:locale/press/:slug',
31 permanent: true,
32 },
33 ];
34 },
35};
36
37module.exports = nextConfig;
01 / 01
STEP 01
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1Storing redirect pairs as data lets you generate config entries with a single map instead of repeating boilerplate.
- 2Next.js redirect sources support named params, wildcards, query conditions via has, and inline regex for precise matching.
- 3permanent: true emits a 308 so browsers and search engines cache the redirect, which matters for SEO on migrated URLs.
Related explainers
javascript
import { createContext, useContext, useReducer, useCallback, useEffect } from 'react'; const AuthContext = createContext(null);
Building an auth context in React
context
usereducer
authentication
Intermediate
8 steps
python
import json import logging import threading from pathlib import Path
A hot-reloading config file watcher
file-watching
thread-safety
hot-reload
Intermediate
7 steps
php
<?php namespace App\Http;
HTTP content negotiation in PHP
http
content-negotiation
parsing
Intermediate
9 steps
javascript
import { useDeferredValue, useMemo, useState } from "react"; function ProductSearch({ products }) { const [query, setQuery] = useState("");
Keeping search input snappy with useDeferredValue in React
concurrent-rendering
deferred-value
memoization
Intermediate
7 steps
typescript
import { InjectionToken, inject, Provider, isDevMode } from '@angular/core'; import { WINDOW } from './window.token'; export interface AnalyticsConfig {
Layered config with an Angular InjectionToken
dependency-injection
configuration
factory-provider
Intermediate
8 steps
javascript
const IBAN_LENGTHS = { DE: 22, FR: 27, GB: 22, ES: 24, IT: 27, NL: 18, BE: 16, CH: 21, AT: 20, PT: 25, };
How IBAN validation works in JavaScript
validation
checksum
modular-arithmetic
Intermediate
8 steps
Share this explainer
Here's the card — post it anywhere.
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code
Embed this explainer
Drop the interactive walkthrough into a blog or docs. Views never cost a credit.
<iframe src="https://highlit.co/explainers/how-redirects-work-in-next-js-config-explained-javascript-9d00/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.