- Background:
I have an SPA (Vuejs) and I implemented the localization both on frontend and backend side. The content is updated successfully without reloading the page when I change the language. - Problem:
But some contents (like product description in the selected language) are coming from an API which is not updated automatically when I change the language. If I refresh the page or call the API again, it works. - Question:
What is the best practice to change language dependent content coming from APIs without page refresh and calling manually all the APIs.
Thanks!
CodePudding user response:
I believe there are many ways of doing what you want to do. For instance. We have models that have some fields that can be localised, but we only support three languages and the fields are relatively short.
In that scenario, we just have the backend rest api return all localised versions of the string, e.g.:
GET /products could return:
[{
sku: '1',
name: {
en: 'Product name',
nl: 'Productnaam',
fr: 'Nom du produit'
}
}]
which we then just show in VueJs based on the route parameter... {{product.name[$route.params.locale] || product.name[en]}} (we have a composable method for this in stead, but you get the idea.
However, for some endpoints you might not always want to return all the localised versions of the server, just because it's too large (e.g. blogposts that you post in multiple languages while you support 5 languages might just generate a payload that you don't want to...)
In such scenario's, you can just watch for changes on your locale in vuejs, and fetch the localised version.
A third option, which I don't like myself, is have the "language switch" basically reload the entire page...
Either way - there's many ways to do what you need, it all depends on your use case, and your personal preference.
CodePudding user response:
I managed to do it, I don't know if it is a best practice, but it is a working solution and can be useful for others:
App.vue:
- I have a
LocaleChanger
component which emitslocalChanged
on every language change. - the views are loaded into
router-view
so I addedrerenderKey
to its key. And when it is changed, everything will be rerendered in the current view(including the APIs of the corresponding components). - And since all of my APIs are called in it, They will be called again.
<template>
<LocaleChanger @localChanged="forceRerender"/>
<div id="nav">
<router-link :to="{ name: 'Home', params: {'lang':$i18n.locale}}">{{$t('pages.home')}}</router-link> |
</div>
<router-view :key="rerenderKey"></router-view>
</template>
<script>
data () {
return {
rerenderKey: 0
};
},
methods: {
async forceRerender(){
await this.$router.push({name: this.$route.name, params: { ...this.$route.params, lang: this.$i18n.locale }})
this.rerenderKey = 1;
},
}
</script>
And since my API-s need the Accept-language
header, I added it in main.js to the axios.interceptors.request
axios.interceptors.request.use(
function (config) {
config.headers['Accept-Language'] = store.state.locale;
return config;
},
function (error) {
return Promise.reject(error);
}
);