Basic Usage

The basics to get started with the Nuxt i18n module is to translate with Vue I18n via the vueI18n option.


Translate with Vue I18n

The basics to get started with Nuxt i18n module is to translate with Vue I18n via the vueI18n option

So, let's get started by adding the module to nuxt.config:

nuxt.config.ts
export default defineNuxtConfig({
  modules: [
    '@nuxtjs/i18n'
  ],
  i18n: {
    vueI18n: './i18n.config.ts' // if you are using custom path, default 
  }
})
i18n.config.ts
export default defineI18nConfig(() => ({
  legacy: false,
  locale: 'en',
  messages: {
    en: {
      welcome: 'Welcome'
    },
    fr: {
      welcome: 'Bienvenue'
    }
  }
}))

The i18n.config file exports the same options as the createI18n function of Vue I18n. The configuration is passed to the createI18n function via the nuxt plugin (runtime) of this module internally.

For more details about configuration, see the Vue I18n documentation.

The following documentation explains how to use the nuxt i18n module using Vue I18n Composition API.For more information on how to use Vue I18n Composition API, please see the docs here.
You can also use Vue I18n's Legacy API in the nuxt i18n module, this requires configuring nuxt.config and i18n.config (legacy: true)

Now, put (or edit) the following the page component in pages directory of your project:

pages/index.vue
<script setup>
const { locale } = useI18n()
</script>

<template>
  <div>
    <form>
      <select v-model="locale">
        <option value="en">en</option>
        <option value="fr">fr</option>
      </select>
      <p>{{ $t('welcome') }}</p>
    </form>
  </div>
</template>
The code demonstrated in this chapter is illustrated using Nuxt Pages.
Some composable functions provided by @nuxtjs/i18n such as useI18n are auto-imported by Nuxt.If you want to import them explicitly, you can use #imports as follows:
<script setup>
import { useI18n, useLocalePath } from '#imports'
// ...
</script>

You now have a really simple Vue I18n based translation environment ready to go! The <select> element contains both English and French options, by choosing either languages from the dropdown, you can see the word "welcome" translate to its corresponding language.

For more information about Vue I18n, you can refer to its documentation here.

The Nuxt i18n module extends the integrated Vue I18n to give us some i18n features for Nuxt application. In here, we introduce one of those features, the link localization with extending Nuxt pages and routing.

Configurations

You'll need to additionally set the defaultLocale and locales options, as in the following configuration.

For localizing links, you can use the code provided from the locales option as the URL path prefix, except for defaultLocale (read more on routing).

nuxt.config.ts
 export default defineNuxtConfig({
   modules: [
     '@nuxtjs/i18n'
   ],
   i18n: {
+    locales: ['en', 'fr'],  // used in URL path prefix
+    defaultLocale: 'en',    // default locale of your project for Nuxt pages and routings
   }
 })

When rendering internal links in your app using <NuxtLink>, you need to get proper URLs for the current locale. To do this, the Nuxt i18n module provides some helper composables:

URL path

You can localize URL paths using useLocalePath.

useLocalePath is a composable which returns a function used to get the localized URL for a given path. The first parameter can either be the path or name of the route or an object for more complex routes. A locale code can be passed as the second parameter to generate a link for a specific language:

<script setup>
const localePath = useLocalePath()
</script>

<template>
  <NuxtLink :to="localePath('index')">{{ $t('home') }}</NuxtLink>
  <NuxtLink :to="localePath('/')">{{ $t('home') }}</NuxtLink>
  <NuxtLink :to="localePath('index', 'en')">Homepage in English</NuxtLink>
  <NuxtLink :to="localePath('/user/profile')">Route by path to: {{ $t('profile') }}</NuxtLink>
  <NuxtLink :to="localePath('user-profile')">Route by name to: {{ $t('profile') }}</NuxtLink>
  <NuxtLink :to="localePath({ name: 'category-slug', params: { slug: category.slug } })">
    {{ category.title }}
  </NuxtLink>
</template>

Note that localePath can use the route's unprefixed path, which must start with '/' or the route's base name to generate the localized URL. The base name corresponds to the names Nuxt generates when parsing your pages directory, more info in Nuxt's doc.

If you prefer to use the Options API, you can use this.localePath. This API is kept for migration from Nuxt 2.

Language switching path

You can localize the language of the current path using useSwitchLocalePath.

useSwitchLocalePath is a composable function which returns a link to the current page in another language:

<script setup>
const switchLocalePath = useSwitchLocalePath()
</script>

<template>
  <NuxtLink :to="switchLocalePath('en')">English</NuxtLink>
  <NuxtLink :to="switchLocalePath('fr')">Français</NuxtLink>
</template>
If you prefer to use the Options API, you can use this.switchLocalePath. This API is kept for migration from Nuxt 2.

URL path with Route object

You can localize advanced URL paths using useLocaleRoute. This is useful if you would to control internal links programmatically.

useLocaleRoute is a composable function that returns a Route object for a given page.

It works like useLocalePath but returns a route resolved by Vue Router rather than a full route path. This can be useful as the path returned from useLocalePath may not carry all information from the provided input (for example, route params that the page doesn't specify).

<script setup>
const localeRoute = useLocaleRoute()
function onClick() {
  const route = localeRoute({ name: 'user-profile', query: { foo: '1' } })
  if (route) {
    return navigateTo(route.fullPath)
  }
}
</script>

<template>
  <button @click="onClick">Show profile</button>
</template>
If you prefer to use the Options API, you can use this.localeRoute. This API is kept for migration from Nuxt 2.