Skip to content

Commit

Permalink
feat: add support for multi domain locales (#3065)
Browse files Browse the repository at this point in the history
Co-authored-by: Vincent de Vreede <[email protected]>
Co-authored-by: DarthGigi <[email protected]>
  • Loading branch information
3 people authored and BobbieGoede committed Aug 19, 2024
1 parent 00c9faa commit 93d6222
Show file tree
Hide file tree
Showing 51 changed files with 1,479 additions and 13 deletions.
170 changes: 170 additions & 0 deletions docs/content/docs/2.guide/10.multi-domain-locales.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
---
title: Multi domain locales
description: Set up multiple domains for multiple locales. Use a different domain name for each language your app supports.
---

How to set up multi domain locales:

- Set the `multiDomainLocales` option to `true`
- Configure the `locales` option as an array of objects:
- Each object has a `domains` key whose value is a array of the domains you'd like to use for that locale. Optionally include a port (if non-standard) and/or a protocol. If the protocol is not provided then an attempt will be made to auto-detect it but that might not work correctly in some cases like when the pages are statically generated.
- Optionally set for each object a `defaultForDomains` key whose value is a array of the default domains you'd like to use for that locale. Optionally include a port (if non-standard) and/or a protocol. If the protocol is not provided then an attempt will be made to auto-detect it but that might not work correctly in some cases like when the pages are statically generated.
- Optionally set `detectBrowserLanguage` to `false`. When enabled (which it is by default), user can get redirected to a different domain on first visit. Set to `false` if you want to ensure that visiting given domain always shows page in the corresponding locale.

```ts [nuxt.config.ts]
const i18nDomains = ['mydomain.com', 'es.mydomain.com', 'fr.mydomain.com', 'http://pl.mydomain.com', 'https://ua.mydomain.com']

export default defineNuxtConfig({
i18n: {
locales: [
{
code: 'en',
domains: i18nDomains,
defaultForDomains: ['mydomain.com']
},
{
code: 'es',
domains: i18nDomains,
defaultForDomains: ['es.mydomain.com']
},
{
code: 'fr',
domains: i18nDomains,
defaultForDomains: ['fr.mydomain.com']
},
{
code: 'pl',
domains: i18nDomains,
defaultForDomains: ['http://pl.mydomain.com']
},
{
code: 'ua',
domains: i18nDomains,
defaultForDomains: ['https://ua.mydomain.com']
},
{
code: 'nl',
domains: i18nDomains
},
{
code: 'de',
domains: i18nDomains
},
],
multiDomainLocales: true
}
})
```

## Runtime environment variables

Sometimes there's a need to change domains in different environments, e.g. staging and production.
As `nuxt.config.ts` is used at build time it would be necessary to create different builds for different environments.

```ts [locale-domains.config.ts]
export const localeDomains = {
uk: process.env.DOMAIN_UK,
fr: process.env.DOMAIN_FR
}
```

```ts [nuxt.config.ts]
import { localeDomains } from './locale-domains.config'

const i18nDomains = [localeDomains.uk, localeDomains.fr]

export default defineNuxtConfig({
modules: ['@nuxtjs/i18n'],

i18n: {
multiDomainLocales: true,
locales: [
{
code: 'uk',
domains: i18nDomains,
defaultForDomains: [localeDomains.uk]
},
{
code: 'fr',
domains: i18nDomains,
defaultForDomains: [localeDomains.fr]
}
]
}
})
```

With the above config, a build would have to be run for staging and production with different .env files that specify `DOMAIN_UK` and `DOMAIN_FR`.

## Using different domains for only some of the languages

If one or more of the domains need to host multiple languages, the default language of each domain needs to have `domainDefault: true` so there is a per domain fallback locale.
The option `differentDomains` still need to be set to `true` though.

```js {}[nuxt.config.js]
const i18nDomains = ['mydomain.com', 'en.mydomain.com', 'es.mydomain.com', 'fr.mydomain.com', 'http://pl.mydomain.com', 'https://ua.mydomain.com']

export default defineNuxtConfig({
// ...
i18n: {
locales: [
{
code: 'en',
domains: i18nDomains,
defaultForDomains: ['mydomain.com', 'en.mydomain.com']
},
{
code: 'es',
domains: i18nDomains,
defaultForDomains: ['es.mydomain.com']
},
{
code: 'fr',
domains: i18nDomains,
defaultForDomains: ['fr.mydomain.com']
},
{
code: 'pl',
domains: i18nDomains,
defaultForDomains: ['http://pl.mydomain.com']
},
{
code: 'ua',
domains: i18nDomains,
defaultForDomains: ['https://ua.mydomain.com']
},
{
code: 'nl',
domains: i18nDomains
},
{
code: 'de',
domains: i18nDomains
},
],
strategy: 'prefix',
multiDomainLocales: true
},
// ...
})
```

Given above configuration with the `prefix` strategy, following requests will be:
- https://mydomain.com -> https://mydomain.com/en (en language)
- https://mydomain.com/pl -> https://mydomain.com/pl (pl language)
- https://mydomain.com/ua -> https://mydomain.com/ua (ua language)
- https://mydomain.com/nl -> https://mydomain.com/nl (nl language)
- https://en.mydomain.com -> https://en.mydomain.com/en (en language)
- https://es.mydomain.com -> https://es.mydomain.com/es (es language)
- https://fr.mydomain.com -> https://fr.mydomain.com/fr (fr language)
- https://fr.mydomain.com/de -> https://fr.mydomain.com/de (de language)

The same requests when using the `prefix_except_default` strategy, will be:
- https://mydomain.com -> https://mydomain.com (en language)
- https://mydomain.com/pl -> https://mydomain.com/pl (pl language)
- https://mydomain.com/ua -> https://mydomain.com/ua (ua language)
- https://mydomain.com/nl -> https://mydomain.com/nl (nl language)
- https://en.mydomain.com -> https://en.mydomain.com (en language)
- https://es.mydomain.com -> https://es.mydomain.com (es language)
- https://fr.mydomain.com -> https://fr.mydomain.com (fr language)
- https://fr.mydomain.com/de -> https://fr.mydomain.com/de (de language)
File renamed without changes.
File renamed without changes.
2 changes: 2 additions & 0 deletions docs/content/docs/3.options/2.routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ When using an object form, the properties can be:
- `dir` - The dir property specifies the direction of the elements and content, value could be `'rtl'`, `'ltr'` or `'auto'`.
- `domain` (required when using [`differentDomains`](/docs/options/domain#differentdomains)) - the domain name you'd like to use for that locale (including the port if used). This property can also be set using [`runtimeConfig`](/docs/options/runtime-config).
- `domainDefault` (required when using [`differentDomains`](/docs/options/domain#differentdomains) while one or more of the domains having multiple locales) - set `domainDefault` to `true` for each locale that should act as a default locale for the particular domain.
- `domains` (required when using [`multiDomainLocales`](/docs/options/domain#multiDomainLocales) while one or more of the domains having multiple of the same locales) - an array of [`domain`].
- `defaultForDomains` (optional when using [`multiDomainLocales`](/docs/options/domain#multiDomainLocales)) - an array of [`domain`] for which the locale should be the default locale when using [`domains`].
- `...` - any custom property set on the object will be exposed at runtime. This can be used, for example, to define the language name for the purpose of using it in a language selector on the page.

You can access all the properties of the current locale through the `localeProperties` property. When using an array of codes, it will only include the `code` property.
Expand Down
7 changes: 7 additions & 0 deletions docs/content/docs/3.options/5.domain.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,10 @@ description: Browser locale management options.
- default: `false`

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.

## `multiDomainLocales`

- type: `boolean`
- default: `false`

Set this to `true` when using different domains with different locales. If enabled, you MUST configure locales as an array of objects, each containing a `domains` and `defaultForDomains` key. Refer to the [Multi Domain Locales](/docs/guide/multi-domain-locales) for more information.
170 changes: 170 additions & 0 deletions docs/content/docs/5.v9/2.guide/10.multi-domain-locales.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
---
title: Multi domain locales
description: Set up multiple domains for multiple locales. Use a different domain name for each language your app supports.
---

How to set up multi domain locales:

- Set the `multiDomainLocales` option to `true`
- Configure the `locales` option as an array of objects:
- Each object has a `domains` key whose value is a array of the domains you'd like to use for that locale. Optionally include a port (if non-standard) and/or a protocol. If the protocol is not provided then an attempt will be made to auto-detect it but that might not work correctly in some cases like when the pages are statically generated.
- Optionally set for each object a `defaultForDomains` key whose value is a array of the default domains you'd like to use for that locale. Optionally include a port (if non-standard) and/or a protocol. If the protocol is not provided then an attempt will be made to auto-detect it but that might not work correctly in some cases like when the pages are statically generated.
- Optionally set `detectBrowserLanguage` to `false`. When enabled (which it is by default), user can get redirected to a different domain on first visit. Set to `false` if you want to ensure that visiting given domain always shows page in the corresponding locale.

```ts [nuxt.config.ts]
const i18nDomains = ['mydomain.com', 'es.mydomain.com', 'fr.mydomain.com', 'http://pl.mydomain.com', 'https://ua.mydomain.com']

export default defineNuxtConfig({
i18n: {
locales: [
{
code: 'en',
domains: i18nDomains,
defaultForDomains: ['mydomain.com']
},
{
code: 'es',
domains: i18nDomains,
defaultForDomains: ['es.mydomain.com']
},
{
code: 'fr',
domains: i18nDomains,
defaultForDomains: ['fr.mydomain.com']
},
{
code: 'pl',
domains: i18nDomains,
defaultForDomains: ['http://pl.mydomain.com']
},
{
code: 'ua',
domains: i18nDomains,
defaultForDomains: ['https://ua.mydomain.com']
},
{
code: 'nl',
domains: i18nDomains
},
{
code: 'de',
domains: i18nDomains
},
],
multiDomainLocales: true
}
})
```

## Runtime environment variables

Sometimes there's a need to change domains in different environments, e.g. staging and production.
As `nuxt.config.ts` is used at build time it would be necessary to create different builds for different environments.

```ts [locale-domains.config.ts]
export const localeDomains = {
uk: process.env.DOMAIN_UK,
fr: process.env.DOMAIN_FR
}
```

```ts [nuxt.config.ts]
import { localeDomains } from './locale-domains.config'

const i18nDomains = [localeDomains.uk, localeDomains.fr]

export default defineNuxtConfig({
modules: ['@nuxtjs/i18n'],

i18n: {
multiDomainLocales: true,
locales: [
{
code: 'uk',
domains: i18nDomains,
defaultForDomains: [localeDomains.uk]
},
{
code: 'fr',
domains: i18nDomains,
defaultForDomains: [localeDomains.fr]
}
]
}
})
```

With the above config, a build would have to be run for staging and production with different .env files that specify `DOMAIN_UK` and `DOMAIN_FR`.

## Using different domains for only some of the languages

If one or more of the domains need to host multiple languages, the default language of each domain needs to have `domainDefault: true` so there is a per domain fallback locale.
The option `differentDomains` still need to be set to `true` though.

```js {}[nuxt.config.js]
const i18nDomains = ['mydomain.com', 'en.mydomain.com', 'es.mydomain.com', 'fr.mydomain.com', 'http://pl.mydomain.com', 'https://ua.mydomain.com']

export default defineNuxtConfig({
// ...
i18n: {
locales: [
{
code: 'en',
domains: i18nDomains,
defaultForDomains: ['mydomain.com', 'en.mydomain.com']
},
{
code: 'es',
domains: i18nDomains,
defaultForDomains: ['es.mydomain.com']
},
{
code: 'fr',
domains: i18nDomains,
defaultForDomains: ['fr.mydomain.com']
},
{
code: 'pl',
domains: i18nDomains,
defaultForDomains: ['http://pl.mydomain.com']
},
{
code: 'ua',
domains: i18nDomains,
defaultForDomains: ['https://ua.mydomain.com']
},
{
code: 'nl',
domains: i18nDomains
},
{
code: 'de',
domains: i18nDomains
},
],
strategy: 'prefix',
multiDomainLocales: true
},
// ...
})
```

Given above configuration with the `prefix` strategy, following requests will be:
- https://mydomain.com -> https://mydomain.com/en (en language)
- https://mydomain.com/pl -> https://mydomain.com/pl (pl language)
- https://mydomain.com/ua -> https://mydomain.com/ua (ua language)
- https://mydomain.com/nl -> https://mydomain.com/nl (nl language)
- https://en.mydomain.com -> https://en.mydomain.com/en (en language)
- https://es.mydomain.com -> https://es.mydomain.com/es (es language)
- https://fr.mydomain.com -> https://fr.mydomain.com/fr (fr language)
- https://fr.mydomain.com/de -> https://fr.mydomain.com/de (de language)

The same requests when using the `prefix_except_default` strategy, will be:
- https://mydomain.com -> https://mydomain.com (en language)
- https://mydomain.com/pl -> https://mydomain.com/pl (pl language)
- https://mydomain.com/ua -> https://mydomain.com/ua (ua language)
- https://mydomain.com/nl -> https://mydomain.com/nl (nl language)
- https://en.mydomain.com -> https://en.mydomain.com (en language)
- https://es.mydomain.com -> https://es.mydomain.com (es language)
- https://fr.mydomain.com -> https://fr.mydomain.com (fr language)
- https://fr.mydomain.com/de -> https://fr.mydomain.com/de (de language)
27 changes: 27 additions & 0 deletions docs/content/docs/5.v9/2.guide/11.locale-fallback.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
title: Locale fallback
description: How a fallback gets selected when a translation is missing.
---

**Nuxt i18n module** takes advantage of **Vue I18n** ability to handle localization fallback. It is possible to define a single fallback locale, an array of locales,
or a decision map for more specific needs.

```js [i18n.config.ts]
export default {
fallbackLocale: 'en',
// or
fallbackLocale: ['en', 'fr'],
// or
fallbackLocale: {
'de-CH': ['fr', 'it'],
'zh-Hant': ['zh-Hans'],
'es-CL': ['es-AR'],
es: ['en-GB'],
pt: ['es-AR'],
default: ['en', 'da']
}
// ...
}
```

More information in [Vue I18n documentation](https://vue-i18n.intlify.dev/guide/essentials/fallback.html)
Loading

0 comments on commit 93d6222

Please sign in to comment.