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.
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):

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:

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.

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 Add → New... if you don't already use JSON files for some translations or Add → Existing file.... Select the file name (e.g. src/locales/en.json) and the language the file contains.

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).

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.