Skip to content

Commit

Permalink
fix: strategy: 'no_prefix' when using differentDomains (#3061)
Browse files Browse the repository at this point in the history
* fix: route localization with `differentDomains`

* fix: prevent route removal

* fix: `switchLocalePath` resolution for `differentDomains`

* docs: update notes to clarify `differentDomains` case
  • Loading branch information
BobbieGoede committed Aug 15, 2024
1 parent c4e2534 commit 53f16e6
Show file tree
Hide file tree
Showing 18 changed files with 508 additions and 33 deletions.
2 changes: 1 addition & 1 deletion docs/content/docs/2.guide/1.index.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ There are 4 supported strategies that affect how app's routes are generated:
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.
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`
Expand Down
2 changes: 1 addition & 1 deletion docs/content/docs/2.guide/3.custom-paths.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ 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 2 ways of configuring custom paths for your [Module configuration](#module-configuration) or your pages [Page component](#page-component).

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

### Module configuration
Expand Down
2 changes: 1 addition & 1 deletion docs/content/docs/2.guide/4.ignoring-localized-routes.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: Customize localized route exclusions per page component.
---

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

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.
Expand Down
2 changes: 1 addition & 1 deletion docs/content/docs/3.options/5.domain.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ description: Browser locale management options.
- type: `boolean`
- default: `false`

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.
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.
2 changes: 1 addition & 1 deletion docs/content/docs/5.v7/7.custom-paths.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ description: nuxt/i18n v7 custom route paths.
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).

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

### In-component options
Expand Down
2 changes: 1 addition & 1 deletion docs/content/docs/5.v7/8.ignoring-localized-routes.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: Ignoring Localized Routes
---

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

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.
Expand Down
92 changes: 92 additions & 0 deletions docs/content/docs/5.v9/2.guide/1.index.md
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'
}

// ...
})
```
243 changes: 243 additions & 0 deletions docs/content/docs/5.v9/2.guide/3.custom-paths.md
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,
}
})
```
Loading

0 comments on commit 53f16e6

Please sign in to comment.