Skip to content

Commit 53f16e6

Browse files
committed
fix: strategy: 'no_prefix' when using differentDomains (#3061)
* fix: route localization with `differentDomains` * fix: prevent route removal * fix: `switchLocalePath` resolution for `differentDomains` * docs: update notes to clarify `differentDomains` case
1 parent c4e2534 commit 53f16e6

File tree

18 files changed

+508
-33
lines changed

18 files changed

+508
-33
lines changed

docs/content/docs/2.guide/1.index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ There are 4 supported strategies that affect how app's routes are generated:
5858
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.
5959

6060
::callout{icon="i-heroicons-light-bulb"}
61-
This strategy doesn't support [Custom paths](/docs/guide/custom-paths) and [Ignore routes](/docs/guide/ignoring-localized-routes) features.
61+
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).
6262
::
6363

6464
### `prefix_except_default`

docs/content/docs/2.guide/3.custom-paths.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ description: Customize the names of the paths for specific locale.
66
In some cases, you might want to translate URLs in addition to having them prefixed with the locale code. There are 2 ways of configuring custom paths for your [Module configuration](#module-configuration) or your pages [Page component](#page-component).
77

88
::callout{icon="i-heroicons-exclamation-triangle" color="amber"}
9-
Custom paths are not supported when using the `no-prefix` [strategy](/docs/guide).
9+
Custom paths are not supported when using the `no_prefix` [strategy](/docs/guide) unless combined with [`differentDomains`](/docs/guide/different-domains).
1010
::
1111

1212
### Module configuration

docs/content/docs/2.guide/4.ignoring-localized-routes.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ description: Customize localized route exclusions per page component.
44
---
55

66
::callout{icon="i-heroicons-exclamation-triangle" color="amber"}
7-
This feature is not supported with the `no-prefix` [strategy](/docs/guide).
7+
This feature is not supported when using the `no_prefix` [strategy](/docs/guide) unless you're also using [`differentDomains`](/docs/guide/different-domains).
88
::
99

1010
If you'd like some pages to be available in some languages only, you can configure the list of supported languages to override the global settings. The options can be specified within either the page components themselves or globally, within the module configuration.

docs/content/docs/3.options/5.domain.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ description: Browser locale management options.
88
- type: `boolean`
99
- default: `false`
1010

11-
Set this to `true` when using different domains for each locale. If enabled, no prefix is added to your routes and you MUST configure locales as an array of objects, each containing a `domain` key. Refer to the [Different domains](/docs/guide/different-domains) for more information.
11+
Set this to `true` when using different domains for each locale, with this enabled you MUST configure locales as an array of objects, each containing a `domain` key. Refer to the [Different domains](/docs/guide/different-domains) for more information.

docs/content/docs/5.v7/7.custom-paths.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ description: nuxt/i18n v7 custom route paths.
66
In some cases, you might want to translate URLs in addition to having them prefixed with the locale code. There are 2 ways of configuring custom paths for your pages: [in-component options](#in-component-options) or via the [module's configuration](#modules-configuration).
77

88
::callout{icon="i-heroicons-light-bulb"}
9-
Custom paths are not supported when using the `no-prefix` [strategy](./strategies).
9+
Custom paths are not supported when using the `no_prefix` [strategy](./strategies).
1010
::
1111

1212
### In-component options

docs/content/docs/5.v7/8.ignoring-localized-routes.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title: Ignoring Localized Routes
33
---
44

55
::callout{icon="i-heroicons-light-bulb"}
6-
This feature is not supported with the `no-prefix` [strategy](./strategies).
6+
This feature is not supported with the `no_prefix` [strategy](./strategies).
77
::
88

99
If you'd like some pages to be available in some languages only, you can configure the list of supported languages to override the global settings. The options can be specified within either the page components themselves or globally, within then module options.
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
---
2+
title: Routing Strategies
3+
description: Nuxt i18n module overrides Nuxt default routes to add locale prefixes to every URL with routing strategies.
4+
---
5+
6+
::callout{icon="i-heroicons-light-bulb"}
7+
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.
8+
::
9+
10+
## Routing
11+
12+
**Nuxt i18n module** overrides Nuxt default routes to add locale prefixes to every URL (except in `no_prefix` strategy).
13+
14+
Say your app supports two languages: French and English as the default language, and you have the following pages in your project:
15+
16+
```
17+
└── pages
18+
├── about
19+
│ └── index.vue
20+
└── index.vue
21+
```
22+
23+
This would result in the following routes being generated
24+
25+
```js
26+
[
27+
{
28+
path: "/",
29+
name: "index___en",
30+
...
31+
},
32+
{
33+
path: "/fr/",
34+
name: "index___fr",
35+
...
36+
},
37+
{
38+
path: "/about",
39+
name: "about___en",
40+
...
41+
},
42+
{
43+
path: "/fr/about",
44+
name: "about___fr",
45+
...
46+
}
47+
]
48+
```
49+
50+
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.
51+
52+
## Strategies
53+
54+
There are 4 supported strategies that affect how app's routes are generated:
55+
56+
### `no_prefix`
57+
58+
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.
59+
60+
::callout{icon="i-heroicons-light-bulb"}
61+
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).
62+
::
63+
64+
### `prefix_except_default`
65+
66+
Using this strategy, all of your routes will have a locale prefix added except for the default language.
67+
68+
### `prefix`
69+
70+
With this strategy, all routes will have a locale prefix.
71+
72+
### `prefix_and_default`
73+
74+
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).
75+
76+
### Configuration
77+
78+
To configure the strategy, use the `strategy` option.
79+
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.
80+
81+
```ts [nuxt.config.ts]
82+
export default defineNuxtConfig({
83+
// ...
84+
85+
i18n: {
86+
strategy: 'prefix_except_default',
87+
defaultLocale: 'en'
88+
}
89+
90+
// ...
91+
})
92+
```
Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
1+
---
2+
title: Custom Route Paths
3+
description: Customize the names of the paths for specific locale.
4+
---
5+
6+
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).
7+
8+
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.
9+
10+
::callout{icon="i-heroicons-exclamation-triangle" color="amber"}
11+
Custom paths are not supported when using the `no_prefix` [strategy](/docs/guide) unless combined with [`differentDomains`](/docs/guide/different-domains).
12+
::
13+
14+
### Module configuration
15+
16+
Make sure you set the `customRoutes` option to `config` and add your custom paths in the `pages` option:
17+
18+
```ts [nuxt.config.ts]
19+
export default defineNuxtConfig({
20+
i18n: {
21+
customRoutes: 'config', // disable custom route with page components
22+
pages: {
23+
about: {
24+
en: '/about-us', // -> accessible at /about-us (no prefix since it's the default locale)
25+
fr: '/a-propos', // -> accessible at /fr/a-propos
26+
es: '/sobre' // -> accessible at /es/sobre
27+
}
28+
}
29+
}
30+
})
31+
```
32+
33+
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 `/`**.
34+
35+
Customized route paths **must start with a `/`** and **not include the locale prefix**.
36+
37+
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`:
38+
39+
```vue
40+
<script setup>
41+
const { t } = useI18n()
42+
</script>
43+
44+
<template>
45+
<NuxtLinkLocale to="about"> {{ t('about') }} </NuxtLinkLocale>
46+
<NuxtLinkLocale to="services-advanced"> {{ t('advanced') }} </NuxtLinkLocale>
47+
</template>
48+
```
49+
50+
Or:
51+
52+
```vue
53+
<script setup>
54+
const { t } = useI18n()
55+
const localePath = useLocalePath()
56+
</script>
57+
58+
<template>
59+
<NuxtLink :to="localePath('about')"> {{ t('about') }} </NuxtLink>
60+
<NuxtLink :to="localePath('services-advanced')"> {{ t('advanced') }} </NuxtLink>
61+
</template>
62+
```
63+
64+
::callout{icon="i-heroicons-exclamation-triangle" color="amber"}
65+
Specifying a path to `localePath` is not supported, currently.
66+
::
67+
68+
#### Example 1: Basic URL localization
69+
70+
You have some routes with the following `pages` directory:
71+
72+
```
73+
pages/
74+
├── about.vue
75+
├── me.vue
76+
├── services/
77+
├──── index.vue
78+
├──── advanced.vue
79+
```
80+
81+
You would need to set up your `pages` property as follows:
82+
83+
```ts [nuxt.config.ts]
84+
export default defineNuxtConfig({
85+
i18n: {
86+
customRoutes: 'config',
87+
pages: {
88+
about: {
89+
fr: '/a-propos',
90+
},
91+
me: {
92+
fr: '/moi',
93+
},
94+
'services/index': {
95+
fr: '/offres',
96+
},
97+
'services/advanced': {
98+
fr: '/offres/avancee',
99+
}
100+
}
101+
}
102+
})
103+
```
104+
105+
If you want customize the URL of a static vue file, you should use the file's name.
106+
If the view is in a sub-directory you should use folder name and vue files name with trailing slash.
107+
108+
::callout{icon="i-heroicons-exclamation-triangle" color="amber"}
109+
All URLs must start with `/`
110+
::
111+
112+
#### Example 2: Localize the part of URL
113+
114+
You have some routes with the following `pages` directory:
115+
116+
```
117+
pages/
118+
├── about.vue
119+
├── services/
120+
├──── coaching.vue
121+
├──── index.vue
122+
├──── development/
123+
├────── app.vue
124+
├────── website.vue
125+
├────── index.vue
126+
```
127+
128+
You would need to set up your `pages` property as follows:
129+
130+
```ts [nuxt.config.ts]
131+
export default defineNuxtConfig({
132+
i18n: {
133+
customRoutes: 'config',
134+
pages: {
135+
about: {
136+
fr: '/a-propos'
137+
},
138+
'services/index': {
139+
fr: '/offres'
140+
},
141+
'services/development/index': {
142+
fr: '/offres/developement'
143+
},
144+
'services/development/app': {
145+
fr: '/offres/developement/app'
146+
},
147+
'services/development/website': {
148+
fr: '/offres/developement/site-web'
149+
},
150+
'services/coaching': {
151+
fr: '/offres/formation'
152+
}
153+
}
154+
}
155+
})
156+
```
157+
158+
If a custom path is missing for one of the locales, the `defaultLocale` custom path is used, if set.
159+
160+
#### Example 3: Dynamic Routes
161+
162+
Say you have some dynamic routes like:
163+
164+
```
165+
pages/
166+
├── blog/
167+
├──── [date]/
168+
├────── [slug].vue
169+
```
170+
171+
Here's how you would configure these particular pages in the configuration:
172+
173+
```ts [nuxt.config.ts]
174+
export default defineNuxtConfig({
175+
i18n: {
176+
customRoutes: 'config',
177+
pages: {
178+
'blog/[date]/[slug]': {
179+
// params need to be put back here as you would with Nuxt Dynamic Routes
180+
// https://nuxt.com/docs/guide/directory-structure/pages#dynamic-routes
181+
ja: '/blog/tech/[date]/[slug]'
182+
// ...
183+
}
184+
}
185+
}
186+
})
187+
```
188+
189+
### Page component
190+
191+
::callout{icon="i-heroicons-exclamation-triangle" color="amber" title="notice"}
192+
Note for those updating to `v8.0.1` or higher
193+
:br :br
194+
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]`)
195+
::
196+
197+
You can use the `defineI18nRoute` compiler macro to set custom paths for each page component.
198+
199+
```html {}[pages/about.vue]
200+
<script setup>
201+
defineI18nRoute({
202+
paths: {
203+
en: '/about-us', // -> accessible at /about-us (no prefix since it's the default locale)
204+
fr: '/a-propos', // -> accessible at /fr/a-propos
205+
es: '/sobre' // -> accessible at /es/sobre
206+
}
207+
})
208+
</script>
209+
```
210+
211+
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):
212+
213+
```html {}[pages/articles/[name].vue]
214+
<script setup>
215+
defineI18nRoute({
216+
paths: {
217+
en: '/articles/[name]',
218+
es: '/artículo/[name]'
219+
}
220+
})
221+
</script>
222+
```
223+
224+
::callout{icon="i-heroicons-light-bulb"}
225+
`defineI18nRoute` compiler macro is tree-shaked out at build time and is not included in the dist files.
226+
::
227+
228+
229+
### `definePageMeta({ name: '...' })` caveat
230+
231+
By default Nuxt overwrites generated route values at build time which breaks custom named routes (setting `name` with `definePageMeta`) when resolving localized paths.
232+
233+
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.
234+
235+
This experimental feature can be enabled as shown here:
236+
237+
```typescript {}[nuxt.config.ts]
238+
export default defineNuxtConfig({
239+
experimental: {
240+
scanPageMeta: true,
241+
}
242+
})
243+
```

0 commit comments

Comments
 (0)