i18n
i18n copied to clipboard
local message are not available in asyncData using `i18n.t()` using vue-i18n-loader
Version
@nuxtjs/i18n: nuxt:
Nuxt configuration
Please change to [x] if relevant for this issue:
- [x] Applies to a site deployed to a static server (site generated with
nuxt generate) - [x] Applies to a site deployed to a server with a Node backend
@nuxtjs/i18n configuration
Reproduction Link
Coming soon
Steps to reproduce
- Create a component
- Add local message using vue-i18n-loader or the option API
- In your asyncData, using
i18n.torapp.i18n.t, the message is not found - If you use global message, it work
What is Expected?
- Local message should also be available as they dont need the instance to be mounted to work since they have no dependancy
What is actually happening?
- Only global message are available
Here is a simplified exemple while I prepare a repro. I need to send my translation to layout component using Vuex.
Component:
<script>
export default {
layout: 'onboarding',
asyncData({ store, app }) {
store.commit('onboarding/setOnboardingDetails', {
title: app.i18n.t('page_title'),
});
},
head() {
return {
title: this.$t('page_title'),
};
},
};
</script>
<i18n lang="json">
{
"fr": {
"page_title": "Introduction",
},
"en": {
"page_title": "Onboarding",
}
}
</i18n>
Layout:
<template>
<div class="layout is-onboarding-layout">
<h1 v-if="details.title" class="onboarding-title">{{ details.title }}</h1>
<nuxt id="content" class="onboarding-content cell small-12 large-auto" />
</div>
</template>
<script>
import { mapState } from 'vuex';
export default {
computed: {
...mapState('onboarding', ['details']),
},
};
</script>
Oh wow. That's one obvious bug that took forever to find :)
@kazupon not sure how familiar you are with Nuxt already but maybe you have some ideas here.
vue-i18n-loaderstores component locales inside the component - https://github.com/intlify/vue-i18n-loader/blob/d1814dae9986088fd4d4d159d88c36f14bd5dbd0/src/index.ts#L45-L46- it only merges the locales and creates local vue-i18n instance once the component is created so after
asyncDatainvocation - We could find the component and the related data within
asyncDataone way or another (maybe not in a pretty way) but then there is a challenge of creating a local (extended) vue-i18n instance just for asyncData and then figuring out when to forget it again. - This all seems like quite a challenge unless I'm missing something (could be since I thought about it for only few minutes).
Alright we are not crazy 😝 We kinda found out a year ago on another project but we were not too familiar with the plugin and we were using local message inside the option API. We ended up moving all these message as global message and didn't think much about it.
But now we moved to vue-i18n-loader and I was refactoring some code on another project and I was hopping the move the text inside the relevant component so that it's easier to find and I figured out it can't be right that local message aren't available inside asyncData.
@rchl Thanks for looking into the issue! I will try to reproduce the issue in my environment first. After that, I'll do some more research on my end. This issue is a good opportunity to understand inside of nuxt. :)
+1 here. Feels like this should already be baked in especially with this being a Nuxt.js specific implementation of vue-i18n.
Does anyone have any workarounds for the moment? Main use case here is error messages (inside of context.error).
To be fair, I've just realized that it's a bit of an anti-pattern to translate in asyncData already as then the translations would not be reactive - wouldn't update when user changes the locale on the client side.
Better approach would be to pass the translation keys around and resolve those within the contexts that are reactive.
Changing the locale re-run asyncData, no ? 🤔 Otherwise how does it fetch my async content in the other language ? It's not "reactive" but the text would still be updated in the correct language
Also since it already work if you use global message, i don't see why that would be an anti-pattern. It's just logical that you would be able to access local message even if the instance is not created yet since the message have no dependancy on the instance. Otherwise if it's so bad you should expose i18n in asyncData at all.
Yes good point.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.