Lazy-load translations
How to lazy-load translations.
For apps that contain a lot of translated content, it is preferable not to bundle all the messages in the main bundle but rather lazy-load only the language that the users selected. This can be achieved with Nuxt i18n module 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 module:
- Set
lazy
option totrue
(or to configuration object if you want to customize some options). - Set
langDir
option to the directory (cannot be empty) that contains your translation files. - Configure
locales
option as an array of objects, where each object has afile
orfiles
key whose value is the translation file corresponding to the locale. - Optionally, remove all messages that you might have passed to Vue I18n via the
vueI18n
option. - Each
file
orfiles
can return either anObject
, or a function that returnsPromise
which must return anObject
.
Basic usage
Example files structure:
nuxt-project/
├── lang/
│ ├── en-US.json
│ ├── es-ES.js
│ ├── fr-FR.ts
├── nuxt.config.ts
Configuration example:
export default defineNuxtConfig({
// ...
i18n: {
locales: [
{
code: 'en',
file: 'en-US.json'
},
{
code: 'es',
file: 'es-ES.js'
},
{
code: 'fr',
file: 'fr-FR.ts'
}
],
lazy: true,
langDir: 'lang',
defaultLocale: 'en'
},
// ...
})
export default defineI18nLocale(async (locale) => {
return {
welcome: 'Welcome'
}
})
// or
export default {
welcome: 'Welcome'
}
defineI18nLocale
composable function.About defineI18nLocale
details, see the here.experimental.jsTsFormatResource
module option to true
.export default defineI18nLocale((locale) => {
// for example, fetch locale messages from nuxt server
return $fetch(`/api/${locale}`)
})
Multiple files lazy loading
The files
property can be used to lazy load multiple files.
This is useful because it is efficient to manage multiple files that only define differences without duplicating locale messages.
For example, let’s take the case of supporting the Spanish language. According to wikipedia, there are 20 countries where Spanish is spoken as an official language!
If these countries are all configured using file
, it would be difficult to maintain due to the duplication of locale messages for each country.
In this scenario, it would be easier to keep all shared (common) locale messages for the target language in a seperate file and define dialectal variations for each country seperately is well to prevent duplication, which is easier to maintain.
The following is an example of a lang directory containing locale files for the Spanish language:
nuxt-project/
├── lang/
│ ├── es.json # locale messages for common Spanish
│ ├── es-AR.json # locale messages for Argentina
│ ├── es-UY.json # locale messages for Uruguay
│ ├── es-US.json # locale messages for Estados Unidos
| ... # other countries ...
├── nuxt.config.ts
The following is an example of the configuration in nuxt.config.ts
:
export default defineNuxtConfig({
// ...
i18n: {
locales: [
// ...
/**
* Example definition with `files` for Spanish speaking countries
*/
{
code: 'es-AR',
name: 'Español (Argentina)',
// lazy loading order: `es.json` -> `es-AR.json`, and then merge 'es-AR.json' with 'es.json'
files: ['es.json', 'es-AR.json']
},
{
code: 'es-UY',
name: 'Español (Uruguay)',
// lazy loading order: `es.json` -> `es-UY.json`, and then merge 'es-UY.json' with 'es.json'
files: ['es.json', 'es-UY.json']
},
{
code: 'es-US',
name: 'Español (Estados Unidos)',
// lazy loading order: `es.json` -> `es-US.json`, and then merge 'es-US.json' with 'es.json'
files: ['es.json', 'es-US.json']
},
// ...
],
lazy: true,
langDir: 'lang',
defaultLocale: 'en',
},
// ...
})
Please not the usage of the files
property, as the above configuration specifies an array containing multiple file names.
@nuxtjs/i18n will load locale messages with lazy loading in the order of the array specified in files
. It then overrides the locale messages in the order in which they were loaded.
In the above es-AR
example, which has es.json
and es-AR.json
defined in files
. In this case, @nuxtjs/i18n lazy-loads es.json
, then it lazy-loads es-AR.json
and overrides es.json
locale messages.
In the example above, only two files are defined for files
, of course you can specify more files over 2 files. In that case, the files will be loaded and override in array order too.
By taking advantage of the characteristic that locale messages are overridden in sequence, it's possible to manage locale messages by defining them on a differential basis. By adding shared (common) locale messages as the first entry of files
, followed by file entries of regional/dialectal locale messages, it's possible to manage resources while avoiding the duplication of locale messages.
Caching
Lazy loaded locale messages are cached based on their filename, file
and files
shared across locales will be used from cache once loaded. By default caching is enabled for static files, and disabled for files that return messages via a function.
Caching can be configured per file by setting file
or entries of files
to objects with the following type signature { path: string, cache?: boolean}
. The example below demonstrates several valid file configurations.
export default defineNuxtConfig({
// ...
i18n: {
locales: [
// ...
/**
* Example definition with `files` for Spanish speaking countries
*/
{
code: 'es-ES',
name: 'Español (Spain)',
// file with cache disabled
file: { path: 'es.js', cache: false }
},
{
code: 'es-AR',
name: 'Español (Argentina)',
// files with cache disabled
files: [{ path: 'es.js', cache: false }, { path: 'es-AR.js', cache: false} ]
},
{
code: 'es-UY',
name: 'Español (Uruguay)',
// strings and object configurations can be mixed
files: [{ path: 'es.js', cache: false }, 'es-UY.json']
},
// ...
],
lazy: true,
langDir: 'lang',
defaultLocale: 'en',
},
// ...
})