- App Router:
localeInPath: 'internal'— a third routing mode for clean URLs and static prerendering per locale. Routes stay underapp/[lng]/, but the proxy rewrites/aboutto/{lng}/aboutinternally (cookie → Accept-Language → fallback), so the public URL never shows a locale while every locale is still prerendered viagenerateStaticParams. Explicit locale paths (/de/about) are served as-is, never redirected, so<Link>prefetches cannot flip the language cookie; switch languages withuseChangeLanguage(). This is the mode for Next.js Cache Components (cacheComponents: true), wherelocaleInPath: falsecannot be used because readingheaders()/cookies()makes every route dynamic. #2345 - App Router:
getT()resolves the language fromnext/root-paramsfirst (Next.js 16.3+) — root params are part of the route key, so unlikeheaders()/cookies()they do not opt a route out of prerendering.await getT('home')in a prerendered[lng]route no longer needs{ lng }threaded through every call site. Falls back to header/cookie detection on older Next.js, in Route Handlers and Server Actions (which have no root params), or when the root layout has no locale segment. #2345 - App Router: languages load on demand —
getT()now callsloadLanguages(lng)and checkshasLoadedNamespace(ns, { lng })for the requested language instead of the instance's own. The default still preloads every supported language; seti18nextOptions: { preload: [] }to load each language on its first request, keeping memory proportional to the locales actually served. #2345 - App Router:
localeParamNameoption — name of the locale route segment (default'lng').generateI18nStaticParams()keys its params by it, so anapp/[locale]segment now prerenders (previously the returned{ lng }silently matched nothing); root-param detection uses the same name.generateI18nStaticParams<'locale'>()narrows the return type. #2345