There is the problem in the main loader. In the documentation of vue-i18n, translations could be defined in the Single page component(
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
i18n: '@kazupon/vue-i18n-loader'
}
}
},
// ...
]
}
The problem is that we don't use 'vue-loader', we use 'eslint-loader' instead in nuxt project. And adding loaders into the config changes nothing. I tried to define new 'push()' with 'vue-loader', but after that, other loaders works incorrectly. Or maybe Vue-i18n-loader is not adaptive for the SSR, so maybe we need nuxt-i18n-loader. And is there a place to be?
Hi, there was a huge revamp in vue-loader by Evan, here's what I've done to make it work :
in vue sfc :
<i18n lang="i18n>
{ awesome stuff }
</i18n>
config.module.rules.push({
test: /\.i18n$/,
loader: `@kazupon/vue-i18n-loader?${JSON.stringify(
{ includePaths: [path.resolve(__dirname), 'node_modules'] }
)}`,
});
@benoitemile That is not working for me 😔
config.module.rules.push({
enforce: "pre",
test: /\.i18n$/,
loader: `@kazupon/vue-i18n-loader?${JSON.stringify({
includePaths: [require("path").resolve(__dirname), "node_modules"]
})}`
})
<i18n lang="i18n">
{
"en": {
"hello": "hello world!"
},
"ru": {
"hello": "Привет мир!"
},
"kz": {
"hello": "Sälem älem!"
}
}
</i18n>
Can you please make sure that you're running vueLoader 15 https://github.com/vuejs/vue-loader/tree/next please ?
@benoitemile Sorry, vue-loader@next crushes styles(I use sass-loader), so I just installed simple vue-lodaer. Nothing changed.
"dependencies": {
"@nuxtjs/axios": "^5.1.1",
"cookieparser": "^0.1.0",
"element-ui": "^2.3.2",
"js-cookie": "^2.2.0",
"nuxt": "^1.4.0",
"nuxt-i18n": "^2.9.1",
"vue-loader": "^14.2.2"
},
"devDependencies": {
"@kazupon/vue-i18n-loader": "^0.3.0",
"autoprefixer": "^8.2.0",
"babel-eslint": "^8.2.2",
"eslint": "^4.19.1",
"eslint-config-prettier": "^2.9.0",
"eslint-friendly-formatter": "^3.0.0",
"eslint-loader": "^1.9.0",
"eslint-plugin-prettier": "^2.6.0",
"eslint-plugin-vue": "^4.4.0",
"jade": "^1.11.0",
"jade-loader": "^0.8.0",
"node-sass": "^4.8.3",
"nuxt-sass-resources-loader": "^1.2.0",
"postcss": "^6.0.21",
"postcss-hexrgba": "^1.0.0",
"postcss-nested": "^3.0.0",
"postcss-responsive-type": "^1.0.0",
"prettier": "^1.11.1",
"sass-loader": "^6.0.7",
"sass-resources-loader": "^1.3.3",
"style-loader": "^0.20.3"
}
hi @adetbekov , here's my package.json atm
"dependencies": {
"@kazupon/vue-i18n-loader": "^0.3.0",
"@nuxtjs/axios": "^5.0.0",
"@nuxtjs/component-cache": "^1.1.1",
"@nuxtjs/dotenv": "^1.1.0",
"@nuxtjs/localforage": "^1.0.2",
"@nuxtjs/proxy": "^1.1.4",
"@nuxtjs/pwa": "^2.0.5",
"@nuxtjs/sentry": "^1.0.1",
"@nuxtjs/toast": "^3.0.0",
"axios": "^0.18.0",
"babel-polyfill": "^6.26.0",
"bootstrap": "^4.0.0",
"bootstrap-vue": "^2.0.0-rc.2",
"file-loader": "^1.1.11",
"fontfaceobserver": "^2.0.13",
"full-icu": "^1.2.1",
"intl": "^1.2.5",
"lazysizes": "^4.0.1",
"newrelic": "^3.1.0",
"node-sass": "^4.8.3",
"nuxt-custom-headers": "^2.0.0",
"nuxt-edge": "^2.0.0",
"nuxt-sass-resources-loader": "nuxt-community/nuxt-sass-resources-loader#feat/v2",
"object-hash": "^1.2.0",
"sass-loader": "^6.0.7",
"sass-resources-loader": "^1.3.3",
"smoothscroll-polyfill": "^0.4.3",
"svg-sprite-loader": "^3.7.1",
"url-loader": "^1.0.1",
"vue-i18n": "^7.6.0",
"vue-i18n-extensions": "^0.1.0",
"vue-loader": "^15.0.0-beta.7",
"vue-slider-component": "^2.5.8",
"vue-styleguidist": "^1.4.9",
"webpack-gcs-plugin": "^0.1.1"
},
"devDependencies": {
"babel-eslint": "^8.2.1",
"babel-jest": "^22.1.0",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"browser-env": "^3.2.4",
"eslint": "^4.18.2",
"eslint-config-airbnb": "^16.1.0",
"eslint-config-prettier": "^2.6.0",
"eslint-config-standard": "^11.0.0-beta.0",
"eslint-loader": "^2.0.0",
"eslint-plugin-html": "^4.0.2",
"eslint-plugin-import": "^2.8.0",
"eslint-plugin-json": "^1.2.0",
"eslint-plugin-jsx-a11y": "^6.0.2",
"eslint-plugin-node": "^6.0.1",
"eslint-plugin-prettier": "^2.5.0",
"eslint-plugin-promise": "^3.5.0",
"eslint-plugin-react": "^7.6.0",
"eslint-plugin-standard": "^3.0.1",
"eslint-plugin-vue": "^4.2.2",
"jest": "^22.1.4",
"jest-junit": "^3.4.1",
"jest-serializer-vue": "^1.0.0",
"postcss-html": "^0.15.0",
"stylelint": "^9.1.2",
"stylelint-config-recommended-scss": "^3.0.0",
"stylelint-config-standard": "^18.2.0",
"stylelint-order": "^0.8.0",
"stylelint-scss": "^2.2.0",
"vue-jest": "^2.1.1",
"vue-test-utils": "^1.0.0-beta.11"
}
here's a part of my nuxt.config.js
build: {
extend(config, ctx) {
config.module.rules.push({
test: /\.i18n$/,
loader: `@kazupon/vue-i18n-loader?${JSON.stringify({
includePaths: [path.resolve(__dirname), 'node_modules']
})}`
});
}
},
plugins: [
'~/plugins/vue-i18n.js'
],
render: {
bundleRenderer: {
directives: {
t: i18nExtensions.directive
}
},
}
here's my vue-i18n.js
import Vue from 'vue';
import VueI18n from 'vue-i18n';
Vue.use(VueI18n);
export default ({ app, store }) => {
const currentApp = app;
currentApp.i18n = new VueI18n({
locale: store.state.i18n.currentLocale.language,
fallbackLocale: 'fr',
});
};
here's a i18n part of a component :
<i18n lang="i18n">
{
"fr": {
"in_stock": "En stock"
},
"en": {
"in_stock": "In stock"
},
"es": {
"in_stock": "some traduction"
},
"de": {
"in_stock": "Auf Lager"
},
"it": {
"in_stock": "Disponibile"
},
"nl": {
"in_stock": "Op voorraad"
},
"pt": {
"in_stock": "In stock"
}
}
</i18n>
and finally the results :
https://i.imgur.com/F066MWU.png
https://i.imgur.com/BYArnvq.png
In the nuxtServerInit, we have some logical to handle marketLanguage from the http request.
Let me know if you're still having issues
Hello everybody, I have an alternative solution, if you are interested.
The problem by adding the webpack configuration like below, is that you overwrite all of vue-loader rules set by Nuxt.
// nuxt.config.js
...
build: {
extend(config, ctx) {
config.module.rules.push({
test: /\.i18n$/,
loader: `@kazupon/vue-i18n-loader?${JSON.stringify({
includePaths: [path.resolve(__dirname), 'node_modules']
})}`
});
}
},
...
A simple console.log() on the webpack configuration:
// Find the rules
console.log( config.module.rules.find( el => el.loader === 'vue-loader' ).options.loaders)
```bash
// Output
{
js:
{ loader: 'babel-loader',
options: { babelrc: false, cacheDirectory: true, presets: [Array] } },
css:
[ { loader: 'vue-style-loader', options: [Object] },
{ loader: 'css-loader', options: [Object] } ],
less:
[ { loader: 'vue-style-loader', options: [Object] },
{ loader: 'css-loader', options: [Object] },
{ options: [Object], loader: 'less-loader' } ],
scss:
[ { loader: 'vue-style-loader', options: [Object] },
{ loader: 'css-loader', options: [Object] },
{ options: [Object], loader: 'sass-loader' } ],
sass:
[ { loader: 'vue-style-loader', options: [Object] },
{ loader: 'css-loader', options: [Object] },
{ options: [Object], loader: 'sass-loader' } ],
stylus:
[ { loader: 'vue-style-loader', options: [Object] },
{ loader: 'css-loader', options: [Object] },
{ options: [Object], loader: 'stylus-loader' } ],
styl:
[ { loader: 'vue-style-loader', options: [Object] },
{ loader: 'css-loader', options: [Object] },
{ options: [Object], loader: 'stylus-loader' } ]
}
## Solution
The simplest way it's to add the configuration like below
```js
// nuxt.config.js
...
build: {
extend(config, ctx) {
config.module.rules.find( el => el.loader === 'vue-loader' ).options.loaders.i18n = '@kazupon/vue-i18n-loader'
}
},
...
Install vue-i18n and @kazupon/vue-i18n-loader (in dev).
package.json
"dependencies": {
"@firebase/app": "^0.1.10",
"@firebase/database": "^0.2.1",
"@nuxtjs/axios": "^5.0.0",
"nuxt": "^1.0.0",
"vue-i18n": "^7.6.0",
"vue-moment": "^3.2.0",
"vuetify": "^0.17.3"
},
"devDependencies": {
"@kazupon/vue-i18n-loader": "^0.3.0",
"yaml-loader": "^0.4.0",
"@std/esm": "^0.26.0",
"cross-env": "^5.0.1",
"esm": "^3.0.14",
"firebase-tools": "^3.17.4",
"stylus": "^0.54.5",
"stylus-loader": "^3.0.1"
}
Create i18n.js plugin.
plugins/i18n.js
import Vue from 'vue';
import VueI18n from 'vue-i18n';
Vue.use(VueI18n);
export default ({app, store}) => {
app.i18n = new VueI18n({
locale: 'ja',
fallbackLocale: 'ja',
});
};
Add plugin to Nuxt
nuxt.config.js
/*
** Plugins to load before mounting the App
*/
plugins: [
'@/plugins/i18n.js',
],
Add <i18n> in component/page/layout template
components/MyComponent
<template>
<div>{{ $t('hello') }}<div/>
</template>
<i18n>
{
"en": {
"hello": "hello world!"
},
"ja": {
"hello": "こんにちは、世界!"
}
}
</i18n>
You can see a sample on my repository: https://github.com/moifort/play-with-nuxt

@moifort @benoitemile Sooorry, but it doesn't work for me at all!
Error:
Cannot read property 'indexOf' of undefined
extend(config, { isDev, isClient, isServer }) {
if (isDev && isClient) {
config.module.rules.push({
enforce: "pre",
test: /\.(js|vue)$/,
loader: "eslint-loader",
exclude: /(node_modules)/
})
}
config.module.rules.find(
el => el.loader === "vue-loader"
).options.loaders.i18n =
"@kazupon/vue-i18n-loader"
if (isServer) {
config.externals = [
nodeExternals({
whitelist: [
/es6-promise|\.(?!(?:js|json)$).{1,5}$/i,
/^vue-awesome/
]
})
]
}
}

I tried to include this trick inside (isDev && isClient) condition, but nothing changed. And I need SSR I18N.
Thanks!
Here is my config https://github.com/adetbekov/acs-front/blob/master/nuxt.config.js
@moifort OMG! OMG! It works after updating some npm packages. THANKS!😭
👍
When I add the vue-i18n-loader via the extend() method in the config, the language switcher breaks. Do any one of you manage to get nuxt-i18n to work properly with vue-i18n-loader?
I'm using nuxt-edge after upgrading to 5.1 I'm getting the following error:
TypeError: Cannot set property 'i18n' of undefined
at Builder.extendBuild.config (/Users/chanlito/Codes/experimental/x-app/node_modules/nuxt-i18n/src/module.js:105:31)
Hi @chanlito
I won't be able to fix this until next week, in the meantime, I'd recommend you disable vueI18nLoader option in your config.
@paulgv I don't think this issue is fixed. I followed all the steps and the language switcher breaks as soon as I add the extend() hook. Have you successfully tested this? If so can you please provide your config? Thanks!
@paulgv can you confirm that the language switcher still works for you with vueI18nLoader: true ?
@karellm I haven't used vue-i18n-loader recently and don't think I've ever tried with a lang switcher actually, the few times I used it was to make some quick prototyping before moving all translations to another file. But there are some issues with this option for sure, I still need to investigate but am lacking time lately...
I'm seeing the same error:
TypeError: Cannot set property 'i18n' of undefined
config.module.rules.find(
el => el.loader === 'vue-loader'
).options.loaders.i18n = '@kazupon/vue-i18n-loader'
The output of vue-loader is:
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
transformAssetUrls: {
video: 'src', source: 'src', object: 'src', embed: 'src'
},
productionMode: false
}
}
Solution for nuxt 2:
config.module.rules.push({
resourceQuery: /blockType=i18n/,
loader: '@kazupon/vue-i18n-loader'
})
vueI18nLoader: true option doesn't work for me with [email protected] if the i18n tag specifies src json files.
Renaming '*.json' files to any arbitrary extension('*.lang' for example) solves this.
Set vueI18nLoader to false and explicitly apply loader config suggested by https://github.com/kazupon/vue-i18n-loader/issues/16#issuecomment-384956906 works.
@moifort
Thank you so much - struggled with the single file component i18n for couple hours and your rule find + change worked perfectly! <3
Most helpful comment
Hello everybody, I have an alternative solution, if you are interested.
Explanation
The problem by adding the webpack configuration like below, is that you overwrite all of
vue-loaderrules set byNuxt.A simple
console.log()on thewebpackconfiguration:```bash
// Output
{
js:
{ loader: 'babel-loader',
options: { babelrc: false, cacheDirectory: true, presets: [Array] } },
css:
[ { loader: 'vue-style-loader', options: [Object] },
{ loader: 'css-loader', options: [Object] } ],
less:
[ { loader: 'vue-style-loader', options: [Object] },
{ loader: 'css-loader', options: [Object] },
{ options: [Object], loader: 'less-loader' } ],
scss:
[ { loader: 'vue-style-loader', options: [Object] },
{ loader: 'css-loader', options: [Object] },
{ options: [Object], loader: 'sass-loader' } ],
sass:
[ { loader: 'vue-style-loader', options: [Object] },
{ loader: 'css-loader', options: [Object] },
{ options: [Object], loader: 'sass-loader' } ],
stylus:
[ { loader: 'vue-style-loader', options: [Object] },
{ loader: 'css-loader', options: [Object] },
{ options: [Object], loader: 'stylus-loader' } ],
styl:
[ { loader: 'vue-style-loader', options: [Object] },
{ loader: 'css-loader', options: [Object] },
{ options: [Object], loader: 'stylus-loader' } ]
}
Full Setup
Install
vue-i18nand@kazupon/vue-i18n-loader(in dev).package.jsonCreate
i18n.jsplugin.plugins/i18n.jsAdd plugin to Nuxt
nuxt.config.jsAdd
<i18n>in component/page/layout templatecomponents/MyComponentYou can see a sample on my repository: https://github.com/moifort/play-with-nuxt