Deviopath › Next.js

Detect the Locale

Medium · Internationalization

Multi-language App Router sites usually put the locale first in the URL (app/[lang]/about/page.tsx serves /fr/about). When a visitor opens a URL **without** a locale, proxy.ts picks one from the browser's Accept-Language header and redirects.

The header lists languages with optional weights: "fr-CH, fr;q=0.9, en;q=0.8". q is between 0 and 1 (default 1); a higher q is preferred and q=0 means "not acceptable".

Write localeRedirect(pathname, acceptLanguage, supported, defaultLocale):

- If the first path segment is already a supported locale (exact match, like /fr or /fr/about), return null (no redirect). /french-food does not count.

- Otherwise parse the header: split on ,, trim, read q= after ;. Skip empty tags, * and entries with q=0. Sort by q (highest first); equal q keeps header order.

- Go through the entries in that order. For each tag, first try an exact match in supported (case-insensitive, return the spelling from supported), then its base language before - (en-US falls back to en). The first hit wins.

- If nothing matches, use defaultLocale.

- Return "/" + locale + pathname, but for "/" return just "/" + locale.

(Real apps often use the negotiator and @formatjs/intl-localematcher packages for this. The simplified rules above are enough here.)

Next: Effective Route Revalidate