How to convert vue-i18n from single file components to JSON

Andreas Löw
How to convert vue-i18n from single file components to JSON

I've written an in-depth article about why you should not use <i18n> sections in your .vue files. For more details, see Why using i18n sections in vue.js single file components is a bad idea.

This tutorial explains how you can make an easy transition to JSON files.

How to convert vue-i18n from single file components to JSON

This tutorial guides you through the following steps

1. Download BabelEdit 3.0.1

You can even use a trial version of BabelEdit to do this - no license required. However, you can only use versions up to 3.0.1. We'll remove vue-sfc support in newer versions.

Download BabelEdit

You need BabelEdit 3.0.1 to do this. Newer versions do not work for this procedure!

2. Import your project into BabelEdit

Drop the project root folder onto BabelEdit it detects the correct project type in most cases.

In some cases, it might ask you which project type to choose. Select vue-i18n (vue files):

Select Project Type vue-i18n (vue files)

You are now asked to confirm the languages you are using in your project in most cases everything should already be populated with the correct data:

Choose the languages for your vue-i18n project

Click Ok.

You should see something similar to the screenshot below: Your Vue.js components appear top-level in the tree on the left side. Below them, you see the translations.

The configured vue-i18n project with single file components

Keep that project open.

3. Create a new Vue.js project in BabelEdit

In BabelEdit select New project from the menu. Choose the vue-i18n (json files) project type.

A good location for the JSON files is src/locales.

For each language in your original project, click AddNew... if you don't already use JSON files for some translations or AddExisting file.... Select the file name (e.g. src/locales/en.json) and the language the file contains.

Select the language for your JSON translation files for your vue-i18n project

Finally, select a Primary Language for this project. The Primary language is used in BabelEdit for machine translation and other useful features.

4. Transfer the translation from the vue-sfc project to the Vue.json project

Select the translations in your vue-sfc project. You can do this in 2 ways depending on how you used the translations in your project.

Most translation IDs are unique

If your translation IDs are unique, you can simply select all items below the .vue file node in the tree on the left side of BabelEdit.

E.g.

  • 📄 src/components/main.vue
    • 💬 title
    • 💬 text
  • 📄 src/components/about.vue
    • 💬 another-title
    • 💬 another-text

Here it's the easiest way to just copy title, text, another-title and another-text.

Many translation IDs are used in different components

If your translation IDs are not unique, you can either rename the IDs to make them unique or copy the whole tree including the file nodes. They'll show up in the target project, too.

E.g. if your structure looks like this:

  • 📄 src/components/main.vue
    • 💬 title
    • 💬 text
  • 📄 src/components/about.vue
    • 💬 title
    • 💬 text

And you copy it over to the JSON project, you'll see the same items. It's important that you now replace src/components/main.vue with main and src/components/about.vue with about in the JSON project afterwards.

You'll also have to change the parts of your code where you reference the IDs from title to main.title in main.vue and title to about.title in the about.vue.

Copying the nodes

Use CTRL+C (Windows) or CMD+C (Mac) to copy the translations.

Switch to the Vue.json project, click in the left panel with the tree view and press CTRL+V (Windows) or CMD+V (Mac) to paste the translations.

If you don't want to use the shortcuts, use the context menu (Right mouse button, Copy and Paste).

Copy translations from vue-sfc to your Vue.json project

5. Cleanup your new project

You might see nodes in the translation tree, that have a number in ´()´ this happens when identical parts of a path are found. BabelEdit does not interleave the translation IDs.

You can easily move nodes or subtrees using copy and paste or the Move to... command in the tree's context menu.

Finally, save the new project. It'll ask you to save a .babel file - that's the project configuration for BabelEdit. After it's saved, it'll also store your .json files in the location specified during setup.

6. Remove <i18n> sections from your components

Ok - as the title already says: Go through your .vue files and get rid of the <i18n> sections.

7. Load the .json files in your project

Adjust the creation of the VueI18n to load the translation files located in the ./locales folder. The example code below should give you an idea how to do that.

Vue.use(VueI18n)

function loadLocaleMessages () {
  const locales = require.context('./locales', true, /[A-Za-z0-9-_,\s]+\.json$/i)
  const messages = {}
  locales.keys().forEach(key => {
    const matched = key.match(/([A-Za-z0-9-_]+)\./i)
    if (matched && matched.length > 1) {
      const locale = matched[1]
      messages[locale] = locales(key)
    }
  })
  return messages
}

export default new VueI18n({
  locale: process.env.VUE_APP_I18N_LOCALE || 'en',
  fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || 'en',
  messages: loadLocaleMessages()
})

Conclusion

Converting your Vue.js with vue-i18n project from translations in single file components to JSON files is not hard to do - but might require a bit manual work.

In the end, the effort is worth it, as the use of JSON files significantly simplifies the handling of translations in the long run.

If you are still in doubt: Read Why using i18n sections in Vue.js single file components is a bad idea.