Next.js Internationalization (i18n) explains how to translate application interfaces, manage dynamic locale routing, and deliver localized metadata.
Internationalized applications use subpath URL segments (like /en/about or /es/about) to target different language preferences.
Organize your App Router using a dynamic [lang] subfolder segment:
app/
└── [lang]/
├── layout.tsx
├── page.tsx
└── about/
└── page.tsx
Define key-value translation dictionaries for supported languages:
// dictionaries/en.json
{
"welcome": "Welcome to our website!",
"about": "About Us"
}
// dictionaries/es.json
{
"welcome": "¡Bienvenido a nuestro sitio web!",
"about": "Sobre Nosotros"
}
Load dictionary files inside async Server Components dynamically:
// app/[lang]/page.tsx
const dictionaries = {
en: () => import('@/dictionaries/en.json').then((module) => module.default),
es: () => import('@/dictionaries/es.json').then((module) => module.default),
};
export default async function HomePage({
params,
}: {
params: Promise<{ lang: 'en' | 'es' }>;
}) {
const { lang } = await params;
const dict = await dictionaries[lang]();
return (
<main className="p-8">
<h1 className="text-3xl font-bold">{dict.welcome}</h1>
</main>
);
}
Redirect users automatically to their preferred browser language in middleware.ts:
// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
const locales = ['en', 'es'];
const defaultLocale = 'en';
export function middleware(request: NextRequest) {
const { pathname } = request.nextUrl;
const pathnameHasLocale = locales.some(
(locale) => pathname.startsWith(`/${locale}/`) || pathname === `/${locale}`
);
if (pathnameHasLocale) return;
// Redirect to default locale if missing in URL
request.nextUrl.pathname = `/${defaultLocale}${pathname}`;
return NextResponse.redirect(request.nextUrl);
}
export const config = {
matcher: ['/((?!_next|favicon.ico|api).*)'],
};
lang Attributes on HTML Tags: Pass locale parameters into the Root Layout <html> tag for accessibility and browser support./en/about and /es/about subpaths so search engines index localized page variations cleanly.i18n routing in Next.js enables multi-language support. Combining dynamic [lang] routes with dictionary files delivers clean localized experiences globally.
Sign in to track your learning journey, earn industry-recognized certificates, and join our elite developer community.
Quick Access With