The multilingual part of my site built with Nuxt

2021-08-10 3 min read

In this article we'll inspect how the multilingual part of my website works.

Current structure:

  • Serves .md files via the @nuxt/content module
  • If a post has multiple versions with the same slug but in a different language's folder, it's loaded when the locale is changed to that language
  • Only one index and post page for all languages
  • Translation files are located in the locales folder in the main directory

Setting up the i18n module

As seen below, I have defined only two languages. The translation files (en.js and tr.js) for these languages are located in the locales folders. With the lazy option set to true, the files will be loaded only when needed. This is not that important though as they are small size files.

I disabled the detectBrowserLanguage option. Since thestrategy is set to prefix_except_default, the language prefix will be added to the address for all languages except the default one: ->

export default {
  // ...
  i18n: {
    strategy: 'prefix_except_default',
    detectBrowserLanguage: false,
    locales: [
      { code: 'en', iso: 'en-US', file: 'en.js' },
      { code: 'tr', iso: 'tr-TR', file: 'tr.js' },
    baseUrl, // baseUrl: ''
    defaultLocale: 'en',
    lazy: true,
    langDir: '~/locales/',

Locale switcher component

There are two flag icons for the supported locales. The flag of the active locale becomes visible. Here's a working example: . Clicking a flag icon switches the locale. This makes more sense, as my site is only available in two languages.

  <span @click="changeLocale">
    <IconTRFlag v-if="currentLocale === 'tr'" />
    <IconGBFlag v-else />

When changing language with changeLocale(), you can keep a record of the language being changed or check it on the new route. So if the URL that's visited after the language change gives a 404 error, you can show an error message saying that the page does not have a translated version in that language, instead of showing a regular 404 error message.

When the language is changed, if it is not the default one, a language prefix will be added to the URL. Otherwise the language prefix will be removed.

Directory structure

Below is the current folder structure I use for my site.

├── notes
│   ├── en
│   └── tr
└── works
    ├── en
    └── tr

Fetching the appropriate content for a locale

From now on, whether you're checking for a post or fetching it, you should always include the language code in your query.

export default {
  async asyncData({ $content, app }) {
    // instead of this
    const notes = await $content(`notes`)

    // use this
    const notes = await $content(`notes`, app.i18n.locale)

There are some other details but I won't talk about them as they are directly related to the installation and use of the @nuxt/content and @nuxtjs/i18n modules.

That's all. This is the entire custom structure I use on my site.

Date: 2021-08-10
Categories: development