-
-
Notifications
You must be signed in to change notification settings - Fork 490
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: configurable directory restructure (#3054)
* feat: i18n dir resolve * feat: i18n dir resolve * test: add restructure test * refactor: file resolution * fix: layer option validation * docs: describe breaking folder structure change * fix: layer validation * chore: update lockfile * test: change fixture structure * feat: `restructureDir` option * docs: describe restructure and compatible option
- Loading branch information
1 parent
9c90089
commit c906a8d
Showing
34 changed files
with
3,252 additions
and
588 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
--- | ||
title: Layers | ||
description: Using layers to extends projects with Nuxt i18n. | ||
--- | ||
|
||
Nuxt i18n module supports layers and will automatically combine i18n configuration of all extended layers. [Read more about layers here](https://nuxt.com/docs/getting-started/layers) | ||
|
||
## Merging strategy | ||
|
||
As described in the [Nuxt layer authoring guide](https://nuxt.com/docs/guide/going-further/layers#multi-layer-support-for-nuxt-modules) | ||
|
||
> - Earlier items in the `_layers` array have higher priority and override later ones | ||
> - The user's project is the first item in the `_layers` array | ||
Mixing locale configuration such as lazy loading objects and strings may not work as expected, Nuxt i18n will attempt to merge layers as best it can. Consistency of i18n configuration between layers will be most effective. | ||
|
||
## Pages & Routing | ||
|
||
Pages in the `pages` directory from extended layers will automatically be merged and have i18n support as if they were part of your project. | ||
|
||
Page routes defined in `i18n.pages` in each layer configuration will be merged as well. | ||
|
||
## Locales | ||
|
||
A project extending a layer set up with the Nuxt i18n module needs no additional set up as shown in this example: | ||
|
||
::code-group | ||
|
||
```ts [nuxt.config.ts] | ||
export default defineNuxtConfig({ | ||
extends: ['my-layer'] | ||
}) | ||
``` | ||
|
||
```ts [my-layer/nuxt.config.ts] | ||
export default defineNuxtConfig({ | ||
modules: ['@nuxtjs/i18n'], | ||
i18n: { | ||
lazy: true, | ||
locales: [ | ||
{ code: 'en', file: 'en.json' }, | ||
{ code: 'nl', file: 'nl.json' } | ||
] | ||
} | ||
}) | ||
``` | ||
|
||
:: | ||
|
||
The project is able to use i18n functionality and the configured locales would be loaded provided by the extended layer. | ||
|
||
### Merging locales | ||
|
||
Locales provided by a project will be merged with those provided by extended layers, this can be done as follows: | ||
|
||
::code-group | ||
|
||
```ts {} [nuxt.config.ts] | ||
export default defineNuxtConfig({ | ||
extends: ['my-layer'], | ||
i18n: { | ||
locales: [{ code: 'en', file: 'en.json' }] | ||
} | ||
}) | ||
``` | ||
|
||
```ts [my-layer/nuxt.config.ts] | ||
export default defineNuxtConfig({ | ||
modules: ['@nuxtjs/i18n'], | ||
i18n: { | ||
lazy: true, | ||
locales: [ | ||
{ code: 'en', file: 'en.json' }, | ||
{ code: 'nl', file: 'nl.json' } | ||
] | ||
} | ||
}) | ||
``` | ||
|
||
:: | ||
|
||
::callout{icon="i-heroicons-light-bulb"} | ||
Note how some options such as `lazy` are inherited, while options such as `locales` need to be set for every layer (project included) providing locale files. | ||
:: | ||
|
||
This example would result in the project supporting two locales (`en`, `nl`) and would add the additional messages added for the `en` locale. | ||
|
||
::code-group | ||
|
||
```ts [project/i18n/locales/en.json] | ||
{ | ||
"title": "foo" | ||
} | ||
``` | ||
|
||
```ts [project/my-layer/i18n/locales/en.json] | ||
{ | ||
"title": "layer title", | ||
"description": "bar" | ||
} | ||
``` | ||
|
||
:: | ||
|
||
The above will result in the following | ||
|
||
```jsonc | ||
{ | ||
// earlier layers take priority | ||
"title": "foo", | ||
"description": "bar" | ||
} | ||
``` | ||
|
||
## VueI18n options | ||
|
||
Options defined in VueI18n configuration files within layers are merged and override each other according to their layers priority. |
85 changes: 85 additions & 0 deletions
85
docs/content/docs/5.v9/2.guide/15.server-side-translations.md
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,85 @@ | ||
--- | ||
title: Server-Side Translations | ||
description: Translate on the server-side and return it as a response. | ||
--- | ||
|
||
You can do the translation on the server-side and return it as a response. The locale messages defined in nuxt i18n module options are integrated, so all you need to do is configure the locale detector. | ||
|
||
::callout{icon="i-heroicons-exclamation-triangle" color="amber"} | ||
**This feature is experimental,** that is supported from v8 RC8. | ||
:: | ||
|
||
## Define locale detector | ||
|
||
For server-side translation, you need to define a locale detector. | ||
|
||
Nuxt i18n exports the `defineI18nLocaleDetector` composable function to define it. | ||
|
||
The following is an example of how to define a detector that detects locale using query, cookie, and header: | ||
|
||
```ts [i18n/localeDetector.ts] | ||
// Detect based on query, cookie, header | ||
export default defineI18nLocaleDetector((event, config) => { | ||
// try to get locale from query | ||
const query = tryQueryLocale(event, { lang: '' }) // disable locale default value with `lang` option | ||
if (query) { | ||
return query.toString() | ||
} | ||
|
||
// try to get locale from cookie | ||
const cookie = tryCookieLocale(event, { lang: '', name: 'i18n_locale' }) // disable locale default value with `lang` option | ||
if (cookie) { | ||
return cookie.toString() | ||
} | ||
|
||
// try to get locale from header (`accept-header`) | ||
const header = tryHeaderLocale(event, { lang: '' }) // disable locale default value with `lang` option | ||
if (header) { | ||
return header.toString() | ||
} | ||
|
||
// If the locale cannot be resolved up to this point, it is resolved with the value `defaultLocale` of the locale config passed to the function | ||
return config.defaultLocale | ||
}) | ||
``` | ||
|
||
The locale detector function is used to detect the locale on the server-side. It's called per request on the server. | ||
|
||
When you define the locale detector, you need to pass the path to the locale detector to the `experimental.localeDetector` option. | ||
|
||
The following is an example of a locale detector configuration defined directly in the Nuxt application: | ||
|
||
```ts [nuxt.config.ts] | ||
export default defineNuxtConfig({ | ||
i18n: { | ||
experimental: { | ||
localeDetector: 'localeDetector.ts' | ||
} | ||
} | ||
}) | ||
``` | ||
|
||
For details on the locale detector function defined by `defineI18nLocaleDetector`, see [here](/docs/api#definei18nlocaledetector). | ||
|
||
## `useTranslation` on eventHandler | ||
|
||
To translate on the server-side , you need to call `useTranslation`. | ||
|
||
Example: | ||
|
||
```ts | ||
// you need to define `async` event handler | ||
export default defineEventHandler(async event => { | ||
// call `useTranslation`, so it return the translation function | ||
const t = await useTranslation(event) | ||
return { | ||
// call translation function with key of locale messages, | ||
// and translation function has some overload | ||
hello: t('hello') | ||
} | ||
}) | ||
``` | ||
|
||
::callout{icon="i-heroicons-light-bulb"} | ||
For the key of the translation function, you can specify the locale messages set in the nuxt-i18n options inside the nuxt.config, or the locale loaded in the i18n.config messages. | ||
:: |
49 changes: 49 additions & 0 deletions
49
docs/content/docs/5.v9/2.guide/18.breaking-changes-in-v9.md
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,49 @@ | ||
--- | ||
title: Breaking Chainges in v9 | ||
description: Follow this guide to upgrade from one major version to the other. | ||
--- | ||
|
||
::callout{icon="i-heroicons-exclamation-triangle" color="amber"} | ||
`nuxtjs/i18n` v9 is still an alpha version | ||
:: | ||
|
||
## Upgrade to Vue I18n v10 | ||
|
||
Vue I18n has been upgraded from v9 to v10. Vue I18n v10 has no major feature additions, but there are some disruptive changes, such as dropping some features that were deprecated in v9 and integrating the API `$tc` into `$t`, which can be used in the Legacy API style | ||
|
||
Check the documentation [here](https://vue-i18n.intlify.dev/guide/migration/breaking10.html#change-t-and-t-overloaded-signature-for-legacy-api-mode) for more information. | ||
|
||
|
||
## Drop `jit` option | ||
|
||
JIT compilation is now the default in Vue I18n v10. | ||
|
||
https://vue-i18n.intlify.dev/guide/migration/breaking10.html#default-enable-for-jit-compilation | ||
|
||
Accordingly, the `jit` option in Nuxt I18n v8 is no longer needed, so this option has been removed. | ||
|
||
## Directory restructure and `langDir` default value | ||
|
||
We now use a default directory structure that is consistent with [directory structure changes in Nuxt 4](https://nuxt.com/docs/getting-started/upgrade#new-directory-structure). | ||
|
||
What changed | ||
* `langDir` now defaults to `locales`. | ||
* All i18n files are resolved relative to `<rootDir>/i18n`, this can be configured with the `restructureDir` option. | ||
|
||
Here is an example of a project structure after this change: | ||
|
||
```sh | ||
app/ | ||
server/ | ||
i18n/ | ||
locales/ | ||
en.json | ||
ja.json | ||
i18n.config.ts | ||
localeDetector.ts | ||
nuxt.config.ts | ||
``` | ||
|
||
Reasons for change | ||
1. Context - i18n files are used both server-side and client-side, using a dedicated `i18n/` folder in the root directory outside `app/` and `server/` makes more sense. | ||
2. Clean - less clutter/fragmentation of i18n files, and should make resolving and loading files easier for us. |
Oops, something went wrong.