Deviopath › Next.js

Locale Routing with a Default Locale Without Prefix

Hard · Proxy

The App Router has no built-in i18n routing: you put pages under app/[locale]/... and decide the locale in proxy.ts (called middleware.ts before Next.js 16). Libraries like next-intl offer an "as-needed" prefix mode: the default locale has no prefix in the URL (/about), other locales do (/de/about). This is a simplified model of that behaviour.

Write routeLocale(config, request). config is { locales, defaultLocale }. request is { pathname, cookie?, acceptLanguage? }; pathname may include a query string (?...) which must be kept unchanged on redirects and rewrites; cookie is the value of the NEXT_LOCALE cookie.

- If the first path segment equals a locale exactly: - the default locale: redirect to the path without it, { action: "redirect", location, locale } (/en/about to /about, /en to /). - another locale: { action: "next", locale }.

- Otherwise detect the locale: the cookie if it is one of locales; else the Accept-Language header; else defaultLocale.

- Accept-Language: split on ,, trim, read q= (default 1), drop entries with q <= 0 and *, sort by q descending (keep header order on ties). For each tag in order: a locale equal to it (case-insensitive) wins; otherwise a locale equal to the part before - wins (de-CH gives de).

- If the detected locale is the default, rewrite (the URL stays, the internal path changes): { action: "rewrite", path: "/" + locale + pathname, locale }, with / becoming /en.

- Otherwise redirect to the prefixed URL: { action: "redirect", location: "/de/about", locale }, with / becoming /de.

Next: Photo Modal with Intercepted Routes