Skip to content

Commit

Permalink
feat(lazy): option for not injecting messages to Nuxt state (#1153)
Browse files Browse the repository at this point in the history
Resolves #1149
  • Loading branch information
rchl authored Apr 18, 2021
1 parent 5e67061 commit 2231f3b
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 10 deletions.
16 changes: 15 additions & 1 deletion docs/content/en/lazy-load-translations.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ For apps that contain a lot of translated content, it is preferable not to bundl
This can be achieved with **nuxt-i18n** by letting the module know where your translation files are located so it can dynamically import them when the app loads or when the user switches to another language.
To enable translations lazy-loading, follow these steps when configuring **nuxt-i18n**:

* Set `lazy` option to `true`.
* Set `lazy` option to `true` (or to [configuration object](#lazy-configuration-options) if you want to customize some options).
* Set `langDir` option to the directory (can not be empty) that contains your translation files.
* Configure `locales` option as an array of object, where each object has a `file` key whose value is the translation file corresponding to the locale.
* Optionally, remove all messages that you might have passed to vue-i18n via `vueI18n` option.
Expand Down Expand Up @@ -73,3 +73,17 @@ Note that if you want to use the `$axios` instance from the `@nuxtjs/axios` modu
This rule in fact applies also to any other module that adds plugins and whose functionality you'd want to use from within that function.

</alert>

## Lazy configuration options

<badge>v6.3.0+</badge>

The `lazy` option can be assigned a configuration object to customize the lazy-loading behavior.

The supported configuration options are:

### `skipNuxtState`

By default, the locale messages for the currently selected locale (unless it happens to be the `fallbackLocale`) are injected into the Nuxt "state" on the server-side and re-used on the client-side. The benefit of that is that the messages are available synchronously on the client-side and an extra network request is avoided. The downside is that it makes each page server response bigger (especially if there is a lot of messages). This applies both to the server-side rendered and statically-generated sites.

With `skipNuxtState` enabled, the locale messages are loaded from respective javascript bundles (for fallback locale from the main bundle and for other locales from their own bundles). This allows the payload to be smaller, but means that the page load might be slower due to an extra request (although browser-side caching will help as much as possible).
17 changes: 14 additions & 3 deletions docs/content/en/options-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,14 +117,25 @@ Routes generation strategy. Can be set to one of the following:

## `lazy`

- type: `boolean`
- type: `boolean` or `LazyOptions`
- default: `false`

Whether the translations should be lazy-loaded. If this is enabled, you MUST configure `langDir` option, and locales must be an array of objects, each containing a `file` key.
See also [Lazy-load translations](/lazy-load-translations).

Whether the translations should be lazy-loaded. If this is enabled, you MUST configure the `langDir` option, and locales must be an array of objects, each containing a `file` key.

Loading locale messages lazily means that only messages for currently used locale (and for the fallback locale, if different from current locale) will be loaded on page loading.

See also [Lazy-load translations](/lazy-load-translations).
#### LazyOptions <badge>v6.3.0+</badge>

The value can also be set to an object instead of the value `true` to override configuration options related to lazy loading. Supports the following optional properties:

**skipNuxtState**

- type: `boolean`
- default: `true`

Whether the translation messages for the current locale should be injected into Nuxt state and re-used on the client-side. [Read more](/lazy-load-translations#lazy-configuration-options).

## `langDir`

Expand Down
16 changes: 15 additions & 1 deletion docs/content/es/lazy-load-translations.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Para las aplicaciones que contienen una gran cantidad de contenido traducido, es
Esto se puede lograr con **nuxt-i18n** al permitir que el módulo sepa dónde se encuentran sus archivos de traducción para que pueda importarlos dinámicamente cuando se carga la aplicación o cuando el usuario cambia a otro idioma.
Para habilitar la carga diferida de traducciones, siga estos pasos cuando configure **nuxt-i18n**:

* Establezca la opción `lazy` en `true`
* Set `lazy` option to `true` (or to [configuration object](#lazy-configuration-options) if you want to customize some options).
* Establezca la opción `langDir` en el directorio (esto NO puede estar vacío) que contiene sus archivos de traducción.
* Configure la opción `locales` como una matriz de objetos, donde cada objeto tiene una clave `file` cuyo valor es el archivo de traducción correspondiente a la configuración local
* Opcionalmente, elimine todos los mensajes que haya pasado a vue-i18n mediante la opción `vueI18n`
Expand Down Expand Up @@ -73,3 +73,17 @@ Note that if you want to use the `$axios` instance from the `@nuxtjs/axios` modu
This rule in fact applies also to any other module that adds plugins and whose functionality you'd want to use from within that function.

</alert>

## Lazy configuration options

<badge>v6.3.0+</badge>

The `lazy` option can be assigned a configuration object to customize the lazy-loading behavior.

The supported configuration options are:

### `skipNuxtState`

By default, the locale messages for the currently selected locale (unless it happens to be the `fallbackLocale`) are injected into the Nuxt "state" on the server-side and re-used on the client-side. The benefit of that is that the messages are available synchronously on the client-side and an extra network request is avoided. The downside is that it makes each page server response bigger (especially if there is a lot of messages). This applies both to the server-side rendered and statically-generated sites.

With `skipNuxtState` enabled, the locale messages are loaded from respective javascript bundles (for fallback locale from the main bundle and for other locales from their own bundles). This allows the payload to be smaller, but means that the page load might be slower due to an extra request (although browser-side caching will help as much as possible).
17 changes: 14 additions & 3 deletions docs/content/es/options-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,14 +117,25 @@ Routes generation strategy. Can be set to one of the following:

## `lazy`

- type: `boolean`
- type: `boolean` or `LazyOptions`
- default: `false`

Whether the translations should be lazy-loaded. If this is enabled, you MUST configure `langDir` option, and locales must be an array of objects, each containing a `file` key.
See also [Lazy-load translations](/lazy-load-translations).

Whether the translations should be lazy-loaded. If this is enabled, you MUST configure the `langDir` option, and locales must be an array of objects, each containing a `file` key.

Loading locale messages lazily means that only messages for currently used locale (and for the fallback locale, if different from current locale) will be loaded on page loading.

See also [Lazy-load translations](/lazy-load-translations).
#### LazyOptions <badge>v6.3.0+</badge>

The value can also be set to an object instead of the value `true` to override configuration options related to lazy loading. Supports the following optional properties:

**skipNuxtState**

- type: `boolean`
- default: `true`

Whether the translation messages for the current locale should be injected into Nuxt state and re-used on the client-side. [Read more](/lazy-load-translations#lazy-configuration-options).

## `langDir`

Expand Down
5 changes: 4 additions & 1 deletion src/templates/plugin.main.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ export default async (context) => {
registerStore(store, options.vuex, options.localeCodes)
}

if (process.server && options.lazy) {
const { lazy } = options
const injectInNuxtState = lazy && (lazy === true || lazy.skipNuxtState !== true)

if (process.server && injectInNuxtState) {
const devalue = (await import('devalue')).default
context.beforeNuxtRender(({ nuxtState }) => {
/** @type {Record<string, import('vue-i18n').LocaleMessageObject>} */
Expand Down
50 changes: 50 additions & 0 deletions test/browser.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,56 @@ describe(`${browserString} (with fallbackLocale, lazy)`, () => {
})
})

describe(`${browserString} (lazy with { skipNuxtState: true} )`, () => {
/** @type {Nuxt} */
let nuxt
/** @type {import('playwright-chromium').ChromiumBrowser} */
let browser
/** @type {import('playwright-chromium').Page} */
let page

beforeAll(async () => {
const overrides = {
i18n: {
defaultLocale: 'pl',
lazy: { skipNuxtState: true },
langDir: 'lang/',
vueI18n: {
fallbackLocale: 'pl'
}
}
}

const localConfig = loadConfig(__dirname, 'basic', overrides, { merge: true })

// Override after merging options to avoid arrays being merged.
localConfig.i18n.locales = [
{ code: 'en', iso: 'en-US', file: 'en-US.js' },
{ code: 'pl', iso: 'pl-PL', file: 'pl-PL.json' },
{ code: 'no', iso: 'no-NO', file: 'no-NO.json' }
]

nuxt = (await setup(localConfig)).nuxt
browser = await createBrowser()
})

afterAll(async () => {
if (browser) {
await browser.close()
}

await nuxt.close()
})

test('current locale messages have not been passed through Nuxt state', async () => {
page = await browser.newPage()
await page.goto(url('/no'))
// @ts-ignore
const i18nState = await page.evaluate(() => window.__NUXT__.__i18n)
expect(i18nState).toBeUndefined()
})
})

describe(`${browserString} (with fallbackLocale, langDir, non-lazy)`, () => {
/** @type {Nuxt} */
let nuxt
Expand Down
6 changes: 5 additions & 1 deletion types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ export interface VuexOptions {
syncRouteParams?: boolean
}

export interface LazyOptions {
skipNuxtState?: boolean
}

// Options that are also exposed on the VueI18n instance.
export interface BaseOptions {
beforeLanguageSwitch?: (oldLocale: string, newLocale: string) => void
Expand All @@ -56,7 +60,7 @@ export interface Options extends BaseOptions {
baseUrl?: string | ((context: NuxtContext) => string)
detectBrowserLanguage?: DetectBrowserLanguageOptions | false
langDir?: string | null
lazy?: boolean
lazy?: boolean | LazyOptions
pages?: {
[key: string]: false | {
[key: string]: false | string
Expand Down

0 comments on commit 2231f3b

Please sign in to comment.