Implement locale-based routing in Next.js App Router using next-intl by creating a centralized routing configuration, setting up a middleware for locale detection and redirection, structuring pages under a [locale] dynamic segment, and configuring request handling for message loading.
Locale-based routing in Next.js using next-intl enables URL prefixes like /en/about and /es/acerca for different languages. This approach is SEO-friendly and provides clear language indicators. The implementation requires five core components: a routing configuration file defining supported locales, a middleware for locale detection and URL rewriting, a request configuration for loading translations, a dynamic [locale] folder structure for pages, and the root layout to provide translations to components.
First, install next-intl and add the plugin to your Next.js configuration. The plugin integrates with the build process to enable i18n features.
The routing.ts file centralizes all routing configuration using defineRouting. It defines supported locales, the default fallback, and the URL prefix strategy. localePrefix: 'always' keeps the locale in all URLs (e.g., /en/about). localePrefix: 'as-needed' removes the prefix for the default locale (e.g., /about for English, /es/about for Spanish). localePrefix: 'never' removes prefixes entirely for domain-based or cookie-based routing.
The createNavigation function exports locale-aware versions of Next.js navigation APIs (Link, redirect, useRouter) that automatically handle the locale prefix.
The request.ts file loads translations for each request. getRequestConfig receives the requestLocale from the middleware, validates it against supported locales, falls back to the default if invalid, and dynamically imports the corresponding JSON message file. This runs on every request, ensuring the correct translations are loaded.
The middleware is the heart of locale-based routing. It handles locale detection, redirects, and rewrites. The detection order is: URL prefix, cookie from a previous visit, accept-language header, and finally the default locale.
For prefix-based routing (default), the workflow is: a user requests /, the middleware detects the locale (e.g., from headers), redirects to /{locale} (e.g., /en), and sets a cookie to remember the preference. Subsequent visits use the cookie.
The matcher configuration ensures the middleware only runs on pages, excluding API routes, static assets, and Next.js internal files.
All pages must be placed inside the [locale] dynamic folder. This folder captures the locale parameter from the URL. The layout.tsx validates the locale, loads messages, and provides them to client components via NextIntlClientProvider.
Optionally, you can create a root page.tsx at app/page.tsx to redirect the base URL to the default locale:
Translations can be accessed in client components using useTranslations() hook or in server components with getTranslations().
The usePathname and useRouter from the navigation helpers maintain the current path while switching the locale. This ensures the user stays on the same page after language change.
For static rendering (SSG), add generateStaticParams to return all locale values, allowing Next.js to pre-render each locale version. Additionally, call setRequestLocale in layouts and pages to make the locale available to Server Components without using dynamic APIs. This must be called before using useTranslations or getMessages.
pathnames allows localization of route paths. Internal pages remain at shared paths (e.g., /about), but external URLs use localized versions (e.g., /über-uns for German). Dynamic segments like [slug] are preserved. The middleware rewrites incoming requests to the shared internal paths.
locales: Array of supported language codes
defaultLocale: Fallback when no match is found
localePrefix: 'always' (default), 'as-needed' (no prefix for default locale), or 'never' (no prefixes)
pathnames: Map internal paths to localized URLs
domains: Map domains to specific locales (e.g., us.example.com → en-US)
localeDetection: Enable/disable automatic detection from headers (default: true)
The complete setup ensures URLs reflect the user's language, provides SEO benefits through proper hreflang tags, and maintains a consistent user experience across language switches.