Vue.js: loop on <i18n> tag

861 views Asked by At

I am using Nuxt.js in static mode to generate my web site, and recently added an i18n module (nuxt-i18n) to support the multi-language ability. Now i want to define translations using custom blocks in my .vue files like that, because they page-specific translations:

<i18n src="./en.json"></i18n>

The problem that when i have 10+ languages it become annoying fast. My question if there is anyway to generate those tags in a loop, for example v-for loop over the $i18.locales variable?

Documentation: nuxt-i18, vue-i18n-loader

1

There are 1 answers

0
Michal Levý On BEST ANSWER

There is a way but definitely not using v-for as it is a Vue construct usable only in Vue templates (<template> block of SFC processed by Vue template compiler)

vue-i18n-loader is just extension of vue-loader (used for processing vue files with Webpack) and works by using it's Custom blocks and Src Imports features. So only ways to solve this is by changing the Webpack build process

Two possible solutions are below. In both cases this adds some complexity into your project so maybe better solution would be to just merge all translations into a single json file...

Option 1 - replace vue-i18n-loader with custom solution

Webpack supports importing json files by default (they are imported as JS objects)

You can use Webpack's require.context() as hinted here. Note that you can place the loadMessages() function in separate file and import it in your components but you have to pass the context in as parameter because parameters of require.context must be literals

...in component/page script block

import loadMessages from `@/utils/loadMessages.js`

const messages = loadMessages(require.context('.', false, /\.json$/i))

export default {
  i18n: {
    messages
  }
}

Similar solution can be created using webpack-import-glob-loader but it requires to change Webpacks config and merging imported "modules" (JS objects) into single messages object...

Option 2 - Writing custom Webpack loader

It shouldn't be too difficult to write your own loader which would expand something like this <i18n src="./*.json"> into multiple <i18n> sections. Changing Webpack config would be also needed. And your loader has to run before vue-loader...