Internationalization (i18n) is a critical feature for modern web applications aiming to reach a global audience. It involves translating your app into multiple languages and adjusting it according to cultural nuances. Nuxt 3, a popular Vue.js framework, provides a straightforward approach to setting up i18n. Here's a comprehensive guide to implementing i18n in your Nuxt 3 project.
npm i -D @nuxtjs/i18n
pnpm add @nuxtjs/i18n --save-dev
yarn add --dev @nuxtjs/i18n
bun add @nuxtjs/i18n
nuxt.config.ts file:export default defineNuxtConfig({
modules: [
'@nuxtjs/i18n',
],
i18n: {
/* module options */
}
})
If you are a beginner You might need to get familiar with some definitions before we start:
https://example.com/ https://example.com/about etc.en fr de etc. it can also be a combination of language and country, for example, en-US fr-CA de-DE etc.https://example.com/<prefix>, for example, https://example.com/en https://example.com/fr https://example.com/de etc.Depending on your project's needs, you can choose from 4 different i18n strategies:
In our example we will use the prefix_except_default strategy and set defaultLocale to en.
export default defineNuxtConfig({
modules: [
'@nuxtjs/i18n',
],
i18n: {
strategy: 'prefix_except_default',
defaultLocale: 'en'
}
})
The locales option is an array of objects that contains the locales you want to support in your application. Each locale object must have a code property that represents the locale code, file property that represents the locale file in your locale folder and a iso property that represents the locale ISO code. The iso property is optional, but it is recommended to use it as it is used by some features like detectBrowserLanguage.
export default defineNuxtConfig({
modules: [
'@nuxtjs/i18n',
],
i18n: {
strategy: 'prefix_except_default',
defaultLocale: 'en',
lazy: true,
langDir: 'locales',
baseUrl: 'https://my-awsome-website.com',
locales: [
{ code: 'bg', name: 'Bulgarian', iso: 'bg-BG', file: 'bg.json' },
{ code: 'cs', name: 'Czech', iso: 'cs-CZ', file: 'cs.json' },
{ code: 'da', name: 'Danish', iso: 'da-DK', file: 'da.json' },
{ code: 'de', name: 'German', iso: 'de', file: 'de.json' },
{ code: 'el', name: 'Greek', iso: 'el-GR', file: 'el.json' },
{ code: 'en', name: 'English', iso: 'en', file: 'en.json' },
{ code: 'es', name: 'Spanish', iso: 'es-ES', file: 'es.json' },
{ code: 'et', name: 'Estonian', iso: 'et-EE', file: 'et.json' },
{ code: 'fi', name: 'Finnish', iso: 'fi-FI', file: 'fi.json' },
{ code: 'fr', name: 'French', iso: 'fr', file: 'fr.json' },
{ code: 'hu', name: 'Hungarian', iso: 'hu-HU', file: 'hu.json' },
{ code: 'id', name: 'Indonesian', iso: 'id-ID', file: 'id.json' },
{ code: 'it', name: 'Italian', iso: 'it-IT', file: 'it.json' },
{ code: 'ja', name: 'Japanese', iso: 'ja-JP', file: 'ja.json' },
{ code: 'ko', name: 'Korean', iso: 'ko-KR', file: 'ko.json' },
{ code: 'lt', name: 'Lithuanian', iso: 'lt-LT', file: 'lt.json' },
{ code: 'lv', name: 'Latvian', iso: 'lv-LV', file: 'lv.json' },
{ code: 'nb', name: 'Norwegian Bokmål', iso: 'nb-NO', file: 'nb.json' },
{ code: 'nl', name: 'Dutch', iso: 'nl-NL', file: 'nl.json' },
{ code: 'pl', name: 'Polish', iso: 'pl-PL', file: 'pl.json' },
{ code: 'pt-br', name: 'Portuguese (Brazil)', iso: 'pt-BR', file: 'pt-br.json' },
{ code: 'pt-pt', name: 'Portuguese (Portugal)', iso: 'pt-PT', file: 'pt-pt.json' },
{ code: 'ro', name: 'Romanian', iso: 'ro-RO', file: 'ro.json' },
{ code: 'ru', name: 'Russian', iso: 'ru-RU', file: 'ru.json' },
{ code: 'sk', name: 'Slovak', iso: 'sk-SK', file: 'sk.json' },
{ code: 'sl', name: 'Slovenian', iso: 'sl-SI', file: 'sl.json' },
{ code: 'sv', name: 'Swedish', iso: 'sv-SE', file: 'sv.json' },
{ code: 'tr', name: 'Turkish', iso: 'tr-TR', file: 'tr.json' },
{ code: 'uk', name: 'Ukrainian', iso: 'uk-UA', file: 'uk.json' },
{ code: 'zh', name: 'Chinese', iso: 'zh-CN', file: 'zh.json' },
],
detectBrowserLanguage: {
useCookie: true,
},
vueI18n: './i18n.config.ts',
}
})
The vueI18n option is the path to the file that contains the configuration for the vue-i18n library. You can also pass the configuration directly to the vueI18n option, but it is recommended to use a separate file for the configuration. create a file named i18n.config.ts in the root of your project and add the following code to it:
export default defineI18nConfig(() => ({
legacy: false,
lazy: true,
strategy: 'prefix_except_default',
langDir: 'locales',
defaultLocale: 'en',
}))
The langDir option is the path to the directory that contains the locale files. The locale files must be named with the locale code and the .json extension, for example, en.json, fr.json, de.json etc. The locale files must be placed in the langDir directory, for example, locales/en.json, locales/fr.json, locales/de.json etc. The locale files must be valid JSON files and must contain a JSON object with the translations for the locale. The keys of the JSON object must be the translation keys and the values must be the translations. The locale files must be valid JSON files and must contain a JSON object with the translations for the locale. The keys of the JSON object must be the translation keys and the values must be the translations.
Here is an example of a locale file for the en locale:
{
"hello": "Hello World!"
}
and here is an example of a locale file for the fr locale:
{
"hello": "Bonjour le monde!"
}
Thanks to the @nuxtjs/i18n module, you can easily use translations in your app. The module injects the $t function into the context of your app, which you can use to translate your app. Here is an example of using the $t function in your app:
<template>
<div>
<h1>{{ $t('hello') }}</h1>
</div>
</template>
You can use $t anywhere whithin your template tags, including in your components, pages, layouts, etc.
Happy coding!