-
-
Notifications
You must be signed in to change notification settings - Fork 486
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* fix: route localization with `differentDomains` * fix: prevent route removal * fix: `switchLocalePath` resolution for `differentDomains` * docs: update notes to clarify `differentDomains` case
- Loading branch information
1 parent
c4e2534
commit 53f16e6
Showing
18 changed files
with
508 additions
and
33 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
--- | ||
title: Routing Strategies | ||
description: Nuxt i18n module overrides Nuxt default routes to add locale prefixes to every URL with routing strategies. | ||
--- | ||
|
||
::callout{icon="i-heroicons-light-bulb"} | ||
This feature works under [Nuxt routing](https://nuxt.com/docs/getting-started/routing). It's assumed that you are using the `pages` directory to control routing. | ||
:: | ||
|
||
## Routing | ||
|
||
**Nuxt i18n module** overrides Nuxt default routes to add locale prefixes to every URL (except in `no_prefix` strategy). | ||
|
||
Say your app supports two languages: French and English as the default language, and you have the following pages in your project: | ||
|
||
``` | ||
└── pages | ||
├── about | ||
│ └── index.vue | ||
└── index.vue | ||
``` | ||
|
||
This would result in the following routes being generated | ||
|
||
```js | ||
[ | ||
{ | ||
path: "/", | ||
name: "index___en", | ||
... | ||
}, | ||
{ | ||
path: "/fr/", | ||
name: "index___fr", | ||
... | ||
}, | ||
{ | ||
path: "/about", | ||
name: "about___en", | ||
... | ||
}, | ||
{ | ||
path: "/fr/about", | ||
name: "about___fr", | ||
... | ||
} | ||
] | ||
``` | ||
|
||
Note that routes for the English version do not have any prefix because it is the default language, see the routing strategies section for more details. | ||
|
||
## Strategies | ||
|
||
There are 4 supported strategies that affect how app's routes are generated: | ||
|
||
### `no_prefix` | ||
|
||
With this strategy, your routes won't have a locale prefix added. The locale will be detected & changed without changing the URL. This implies that you have to rely on browser & cookie detection, and implement locale switches by calling the i18n API. | ||
|
||
::callout{icon="i-heroicons-light-bulb"} | ||
This strategy doesn't support [Custom paths](/docs/guide/custom-paths) and [Ignore routes](/docs/guide/ignoring-localized-routes) features unless you're also using [`differentDomains`](/docs/guide/different-domains). | ||
:: | ||
|
||
### `prefix_except_default` | ||
|
||
Using this strategy, all of your routes will have a locale prefix added except for the default language. | ||
|
||
### `prefix` | ||
|
||
With this strategy, all routes will have a locale prefix. | ||
|
||
### `prefix_and_default` | ||
|
||
This strategy combines both previous strategies behaviours, meaning that you will get URLs with prefixes for every language, but URLs for the default language will also have a non-prefixed version (though the prefixed version will be preferred when `detectBrowserLanguage` is enabled). | ||
|
||
### Configuration | ||
|
||
To configure the strategy, use the `strategy` option. | ||
Make sure that you have a `defaultLocale` defined, especially if using `prefix_except_default`, `prefix_and_default` or `no_prefix` strategy. For other strategies it's also recommended to set this as it will be used as a fallback when attempting to redirect from a 404 page. | ||
|
||
```ts [nuxt.config.ts] | ||
export default defineNuxtConfig({ | ||
// ... | ||
|
||
i18n: { | ||
strategy: 'prefix_except_default', | ||
defaultLocale: 'en' | ||
} | ||
|
||
// ... | ||
}) | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,243 @@ | ||
--- | ||
title: Custom Route Paths | ||
description: Customize the names of the paths for specific locale. | ||
--- | ||
|
||
In some cases, you might want to translate URLs in addition to having them prefixed with the locale code. There are two methods of configuring custom paths, through [Module configuration](#module-configuration) or from within each [Page component](#page-component). | ||
|
||
Which method is used is configured by setting the [`customRoutes` options](/docs/options/routing#customroutes) this is set to `'page'` by default. Using both methods at the same time is not possible. | ||
|
||
::callout{icon="i-heroicons-exclamation-triangle" color="amber"} | ||
Custom paths are not supported when using the `no_prefix` [strategy](/docs/guide) unless combined with [`differentDomains`](/docs/guide/different-domains). | ||
:: | ||
|
||
### Module configuration | ||
|
||
Make sure you set the `customRoutes` option to `config` and add your custom paths in the `pages` option: | ||
|
||
```ts [nuxt.config.ts] | ||
export default defineNuxtConfig({ | ||
i18n: { | ||
customRoutes: 'config', // disable custom route with page components | ||
pages: { | ||
about: { | ||
en: '/about-us', // -> accessible at /about-us (no prefix since it's the default locale) | ||
fr: '/a-propos', // -> accessible at /fr/a-propos | ||
es: '/sobre' // -> accessible at /es/sobre | ||
} | ||
} | ||
} | ||
}) | ||
``` | ||
|
||
Note that each key within the `pages` object should **correspond to the relative file-based path (excluding `.vue` file extension) of the route within your `pages/` directory excluding the leading `/`**. | ||
|
||
Customized route paths **must start with a `/`** and **not include the locale prefix**. | ||
|
||
You can now use the `localePath` function or the `<NuxtLinkLocale>` component but be sure to use named routes. For example route `/services/advanced` should be `services-advanced`: | ||
|
||
```vue | ||
<script setup> | ||
const { t } = useI18n() | ||
</script> | ||
<template> | ||
<NuxtLinkLocale to="about"> {{ t('about') }} </NuxtLinkLocale> | ||
<NuxtLinkLocale to="services-advanced"> {{ t('advanced') }} </NuxtLinkLocale> | ||
</template> | ||
``` | ||
|
||
Or: | ||
|
||
```vue | ||
<script setup> | ||
const { t } = useI18n() | ||
const localePath = useLocalePath() | ||
</script> | ||
<template> | ||
<NuxtLink :to="localePath('about')"> {{ t('about') }} </NuxtLink> | ||
<NuxtLink :to="localePath('services-advanced')"> {{ t('advanced') }} </NuxtLink> | ||
</template> | ||
``` | ||
|
||
::callout{icon="i-heroicons-exclamation-triangle" color="amber"} | ||
Specifying a path to `localePath` is not supported, currently. | ||
:: | ||
|
||
#### Example 1: Basic URL localization | ||
|
||
You have some routes with the following `pages` directory: | ||
|
||
``` | ||
pages/ | ||
├── about.vue | ||
├── me.vue | ||
├── services/ | ||
├──── index.vue | ||
├──── advanced.vue | ||
``` | ||
|
||
You would need to set up your `pages` property as follows: | ||
|
||
```ts [nuxt.config.ts] | ||
export default defineNuxtConfig({ | ||
i18n: { | ||
customRoutes: 'config', | ||
pages: { | ||
about: { | ||
fr: '/a-propos', | ||
}, | ||
me: { | ||
fr: '/moi', | ||
}, | ||
'services/index': { | ||
fr: '/offres', | ||
}, | ||
'services/advanced': { | ||
fr: '/offres/avancee', | ||
} | ||
} | ||
} | ||
}) | ||
``` | ||
|
||
If you want customize the URL of a static vue file, you should use the file's name. | ||
If the view is in a sub-directory you should use folder name and vue files name with trailing slash. | ||
|
||
::callout{icon="i-heroicons-exclamation-triangle" color="amber"} | ||
All URLs must start with `/` | ||
:: | ||
|
||
#### Example 2: Localize the part of URL | ||
|
||
You have some routes with the following `pages` directory: | ||
|
||
``` | ||
pages/ | ||
├── about.vue | ||
├── services/ | ||
├──── coaching.vue | ||
├──── index.vue | ||
├──── development/ | ||
├────── app.vue | ||
├────── website.vue | ||
├────── index.vue | ||
``` | ||
|
||
You would need to set up your `pages` property as follows: | ||
|
||
```ts [nuxt.config.ts] | ||
export default defineNuxtConfig({ | ||
i18n: { | ||
customRoutes: 'config', | ||
pages: { | ||
about: { | ||
fr: '/a-propos' | ||
}, | ||
'services/index': { | ||
fr: '/offres' | ||
}, | ||
'services/development/index': { | ||
fr: '/offres/developement' | ||
}, | ||
'services/development/app': { | ||
fr: '/offres/developement/app' | ||
}, | ||
'services/development/website': { | ||
fr: '/offres/developement/site-web' | ||
}, | ||
'services/coaching': { | ||
fr: '/offres/formation' | ||
} | ||
} | ||
} | ||
}) | ||
``` | ||
|
||
If a custom path is missing for one of the locales, the `defaultLocale` custom path is used, if set. | ||
|
||
#### Example 3: Dynamic Routes | ||
|
||
Say you have some dynamic routes like: | ||
|
||
``` | ||
pages/ | ||
├── blog/ | ||
├──── [date]/ | ||
├────── [slug].vue | ||
``` | ||
|
||
Here's how you would configure these particular pages in the configuration: | ||
|
||
```ts [nuxt.config.ts] | ||
export default defineNuxtConfig({ | ||
i18n: { | ||
customRoutes: 'config', | ||
pages: { | ||
'blog/[date]/[slug]': { | ||
// params need to be put back here as you would with Nuxt Dynamic Routes | ||
// https://nuxt.com/docs/guide/directory-structure/pages#dynamic-routes | ||
ja: '/blog/tech/[date]/[slug]' | ||
// ... | ||
} | ||
} | ||
} | ||
}) | ||
``` | ||
|
||
### Page component | ||
|
||
::callout{icon="i-heroicons-exclamation-triangle" color="amber" title="notice"} | ||
Note for those updating to `v8.0.1` or higher | ||
:br :br | ||
Path parameters parsing has been changed to match that of [Nuxt 3](https://nuxt.com/docs/guide/directory-structure/pages#dynamic-routes), you will have to update your custom paths (e.g. `/example/:param` should now be `/example/[param]`) | ||
:: | ||
|
||
You can use the `defineI18nRoute` compiler macro to set custom paths for each page component. | ||
|
||
```html {}[pages/about.vue] | ||
<script setup> | ||
defineI18nRoute({ | ||
paths: { | ||
en: '/about-us', // -> accessible at /about-us (no prefix since it's the default locale) | ||
fr: '/a-propos', // -> accessible at /fr/a-propos | ||
es: '/sobre' // -> accessible at /es/sobre | ||
} | ||
}) | ||
</script> | ||
``` | ||
|
||
To configure a custom path for a dynamic route, you need to use it in double square brackets in the paths similarly to how you would do it in [Nuxt Dynamic Routes](https://nuxt.com/docs/guide/directory-structure/pages#dynamic-routes): | ||
|
||
```html {}[pages/articles/[name].vue] | ||
<script setup> | ||
defineI18nRoute({ | ||
paths: { | ||
en: '/articles/[name]', | ||
es: '/artículo/[name]' | ||
} | ||
}) | ||
</script> | ||
``` | ||
|
||
::callout{icon="i-heroicons-light-bulb"} | ||
`defineI18nRoute` compiler macro is tree-shaked out at build time and is not included in the dist files. | ||
:: | ||
|
||
|
||
### `definePageMeta({ name: '...' })` caveat | ||
|
||
By default Nuxt overwrites generated route values at build time which breaks custom named routes (setting `name` with `definePageMeta`) when resolving localized paths. | ||
|
||
Nuxt v3.10 introduced the experimental feature [`scanPageMeta`](https://nuxt.com/docs/guide/going-further/experimental-features#scanpagemeta), this needs to be enabled for custom named routes to work when using Nuxt I18n. | ||
|
||
This experimental feature can be enabled as shown here: | ||
|
||
```typescript {}[nuxt.config.ts] | ||
export default defineNuxtConfig({ | ||
experimental: { | ||
scanPageMeta: true, | ||
} | ||
}) | ||
``` |
Oops, something went wrong.