Implement internationalization in Next.js using next-intl by installing the library, configuring the plugin, setting up request configuration, and optionally adding locale-based routing with middleware for URL prefixing.
next-intl is the recommended solution for internationalization (i18n) in Next.js App Router applications. It provides comprehensive i18n support including translations, date/number formatting, and internationalized routing. The library integrates seamlessly with both Server and Client Components and offers two main setup approaches: without i18n routing (simpler, single-language or user-specified locale) and with i18n routing (URL-based locale prefixes like /en/about).
This approach is ideal for single-language apps or when you want to determine locale based on user settings (like cookies) rather than URL prefixes. No middleware or [locale] folder is needed.
This approach adds locale prefixes to URLs (e.g., /en/about, /es/acerca) and is recommended for SEO and multi-language apps. It requires middleware, a [locale] dynamic folder, and routing configuration.
localePrefix: 'always' (default) keeps locale in all URLs. 'as-needed' removes prefix for default locale (e.g., /about instead of /en/about). 'never' removes all prefixes (use with domain-based routing or cookies).
pathnames: Localize route pathnames (e.g., /about in English, /uber-uns in German). Supports dynamic segments like /news/[slug].
domains: Map domains to specific locales (e.g., us.example.com for English, fr.example.com for French). Useful for country-specific sites.
cookie-based locale detection: Disable middleware's built-in detection with localeDetection: false and implement custom detection reading from cookies or headers.
Translation messages are stored as JSON files, one per locale. Use a hierarchical structure with namespaces (top-level keys) corresponding to component names. This allows for better organization and enables selective loading. For client components, NextIntlClientProvider makes messages available via context. For server components, messages are loaded per request through the request configuration.