Routing strategies
The strategy option decides whether a locale appears in the URL and for which locales. Pick it once, before you publish URLs: changing it later changes every link. The module then generates the localized routes at build time, and $localePath, <i18n-link> and the switcher read them.
The four strategies
Type Strategies · Default 'prefix_except_default'
URL routing strategy for locale prefixes.
'no_prefix'— no locale in URL; locale stored in cookie.'prefix_except_default'— prefix all locales except the default.'prefix'— always prefix, including the default locale.'prefix_and_default'— likeprefix, but the default locale is also accessible without prefix.
URLs for an about page with defaultLocale: 'en' and locales en, de:
| Strategy | English | German | Not served |
|---|---|---|---|
prefix_except_default (default) | /about | /de/about | /en and /en/about are a 404 |
prefix | /en/about | /de/about | /about redirects to a prefixed URL |
prefix_and_default | /about and /en/about | /de/about | — |
no_prefix | /about | /about | the locale is not in the URL |
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['nuxt-i18n-micro'],
i18n: {
locales: [
{ code: 'en', iso: 'en-US' },
{ code: 'de', iso: 'de-DE' },
],
defaultLocale: 'en',
strategy: 'prefix',
},
})
The strategy is fixed at build: a runtime override of it is ignored with a warning (Runtime overrides).
Which one to choose
prefix_except_default: most sites. Existing unprefixed URLs keep working for the default language.prefix: every language is equal;/always leads to a prefixed home.prefix_and_default: you need/en/...and the unprefixed URLs both to work, for example while moving from one to the other. Unprefixed URLs are never redirected.no_prefix: apps behind a login, or one URL per page for every language. The locale comes from a cookie or?locale=. Search engines see one language per URL, so nohreflangalternates are emitted.
How the locale is picked for a URL, and when a visitor is redirected, is on Locale detection.
Generated routes
At build time every page gets the route records its strategy needs. Each record carries meta.i18n = { name, locales }: the page it shows and the locales it serves. Links, switches and redirects are all answered from those records, so a URL the module hands out is always one the router serves.
Locales that share the page's path share one record, /:locale(de|fr)/about. A locale with its own path gets its own record, named localized-<page>-<locale>:
// nuxt.config.ts: German has its own path for the about page
i18n: {
globalLocaleRoutes: { about: { de: '/ueber-uns' } },
}
// prefix_except_default, locales en (default), de, fr:
// about /about
// localized-about /:locale(fr)/about
// localized-about-de /:locale(de)/ueber-uns
Custom paths, per-page locale lists and excluding a page from localization are on Localized paths and Page config. The localized- prefix is localizedRouteNamePrefix.
localized-… names in router.push({ name }). Pass the page's own name to $localeRoute or <i18n-link>; they pick the right record.Linking to a page in a locale
<script setup lang="ts">
const { localePath, localeRoute, switchLocalePath } = useI18n()
localePath({ name: 'about' }) // '/de/ueber-uns' while the page is German
localePath({ name: 'about' }, 'en') // '/about'
localePath('/about', 'de') // '/de/ueber-uns': a path is read as the page it shows
localeRoute({ name: 'products-id', params: { id: '42' } }, 'de') // resolved route: name, params, fullPath
switchLocalePath('fr') // the current page in French
</script>
<template>
<i18n-link :to="{ name: 'about' }">{{ $t('nav.about') }}</i18n-link>
<NuxtLink :to="$switchLocalePath('de')">Deutsch</NuxtLink>
</template>
- Named routes and paths both work. A path is matched against the generated routes, so any locale's form of it is accepted.
- A locale that does not serve the page (see
localesin Page config) links to that locale's home instead of a missing page. - Per-locale params (a translated slug) go through
$setI18nRouteParams, see Localized paths.
Signatures are in Methods.
no_prefix details
localeCookiedefaults to'user-locale'underno_prefix, so the choice survives a reload.$switchLocale('de')loads the German dictionary and replaces the current history entry; the URL does not change.- Custom per-locale paths still work: with
globalLocaleRoutes: { about: { de: '/ueber-uns' } }, German readers get/ueber-uns. That URL always renders German, whatever the visitor prefers, and a page restricted to some locales renders in one of them. A path several locales share (enanddeboth on/page/:id) renders the preference when it is one of them. The preference itself stays: the next page returns to it. noPrefixRedirect: trueredirects the original path of a page with a custom path in the default locale: to the custom path of the visitor's locale, the default locale's otherwise (/about→/about-uswhenenhas/about-us, →/ueber-unswith cookiede). A locale with no custom path of its own stays on the original path and renders there. Pages with params are not redirected.
Apps without pages/
With pages: false there are no page routes to localize. Use root translation files only (disablePageLocales: true); detection, the cookie and $switchLocale still work. The pages-false variant of test/fixtures/basic in the repository is a working setup.