Closed coremyslo closed 2 months ago
these requests are sent again on the client
Not anymore in latest versions. nuxtState
is used to carry over server-loaded messages (when using lazy
).
BTW. As for your current solution, the problem I see with it is that when the user switches locale (or navigates to another locale) on the client, then your logic in nuxtServerInit
won't run. How do you handle that?
I think the absolutely correct solution might actually require using lazy
and let module load the locales.
to change locale with differentDomains: true
the domain will change, page reload would happen in this case, realtime change of locale doesn't have sense in differentDomains mode.
True that.
Some managing translation services provide tools for in-context live translation edit. This is not my case, but just example of how this feature can be used https://docs.lokalise.com/en/articles/1592525-livejs-web-in-context-editor https://help.phrase.com/help/set-up-in-context-editor
Also developing some sort of cms to manage translations and change messages without reload could be an another case.
Both cases nuxtStore would solve.
I mean, technically it's already supported by using lazy
and having custom loading logic in your code.
It's just that you want to do it differently for the purpose of optimizing for your use case.
BTW. While I intend to fix this, you could create a plugin that fetches data from your API and injects it into the context (on the server only). Then you could use that data both from nuxtServerInit
and your custom locale loading code. You would have your optimization and also better organization.
Not anymore in latest versions. nuxtState is used to carry over server-loaded messages (when using lazy).
There is one bug here, If I provide defaultLocale
and load domain in browser where domain locale match defaultLocale
I would see the call on client for that domain with nuxt 2.14.1
and nuxt-i18n 6.13.6
, except that, for my case, I can use lazy.
BTW. While I intend to fix this, you could create a plugin that fetches data from your API and injects it into the context (on the server only). Then you could use that data both from nuxtServerInit and your custom locale loading code. You would have your optimization and also better organization.
hm, I was thinking on using store instead, If the messages could be in store state in i18n module, I could call the mutation from it, from my store module action, which I'll use in nuxtServerInit
I mean, technically it's already supported by using lazy and having custom loading logic in your code. It's just that you want to do it differently for the purpose of optimizing for your use case.
well, technically I can, after your note about fixes with not having calls on client. But I believe context.app.i18n.setLocaleMessage
was indented to add the ability to change messages after page loaded, which is not working in i18n-module
, I'm honestly not sure, didn't test vue-i18n
without i18n-module
in nuxt. But the fix should open new opportunities not only for my case, noted above.
I am probably missing something, but as far as I understand we can't use Translation APIs along with nuxt-i18n. If that's true, it's not about optimizing a specific use case, that means we can't dynamically translate messages. In my case : I have 1600 products in my shop, I want to call the Google Cloud Translation API each time a product page is displayed to translate product description. I would like to use lazy option, but I cannot have 1600 * (number of locales) message files. Moreover, I don't want to regenerate files and translate all the shop everytime a simple change is made.
So : I just want to translate messages in asyncData
function, and use payload in $t(...)
, but it does not seem possible currently.
What would be the nuxt-i18n way to do this ?
A workaround would be to use setLocaleMessage
in asyncData
, but as stated above, it is overridden client side.
I would like to use lazy option, but I cannot have 1600 * (number of locales) message files. Moreover, I don't want to regenerate files and translate all the shop everytime a simple change is made.
You can assign same JS "lang" file for all locales and load translations dynamically using javascript.
So : I just want to translate messages in
asyncData
function, and use payload in$t(...)
, but it does not seem possible currently. What would be the nuxt-i18n way to do this ?A workaround would be to use
setLocaleMessage
inasyncData
, but as stated above, it is overridden client side.
I think that the setLocaleMessage
"workaround" that you've mentioned is actually the proper way to do it if not using "lazy" option.
And the messages should not get overridden on the client with latest nuxt-i18n
versions.
(I might be missing something that makes those solutions not work...)
I am in SSG mode so I would like to use the messages in payload (translated at build time at nuxt generate
). I probably misunderstood the purpose of the lazy option but it does not seem suitable to the SSG case.
Concerning the setLocaleMessage
function, with nuxt-i18n at ^6.13.9
version, it works when navigating but not when coming for the first time, nor when refreshing (but I only tried in SSG mode)
I can make a minimal repro in a new issue if necessary.
I use it this way:
export default {
async asyncData({ payload, app }) {
app.i18n.setLocaleMessage('en', {
title: 'My title'
})
}
}
Is this the way to do ? But then only 'title' is displayed, and if I navigate and come back, 'My title' is displayed.
Right, setLocaleMessage
from asyncData
will work on the server but the client will overwrite it.
Also, it won't work for you if you want to update translations without regenerating the site.
I have a feeling, like you said, that you might be better of not using nuxt-i18n
in this case but feel free to create new issue/question if you want to discuss this further.
I tried to:
messages
as {"source": "nuxtConfig"}
in nuxt.config.jssetLocaleMessage
with { "source": "nuxtServerInit" }
in nuxtServerInitsetLocaleMessage
with { "source": "plugin" }
in my pluginThe order of execution was like this:
// server
{ source: "nuxtConfig" }
{ source: "plugin" }
{ source: "nuxtServerInit" }
// client
{ source: "nuxtConfig" }
{ source: "plugin" }
I believe nuxt-i18n
looks to be a plugin called on server-side and client, and the context changed after nuxt-i18n
execution on server (in my plugin, and nuxtServerInit) was ignored on the client call.
In browser "nuxtServerInit" text displays, changing to "plugin" after client call.
Is it possible to not call the plugin on client-side, or to make client call see the data changed after other plugins and nuxtServerInit calls?
That's why you should utilize "lazy" option. Then messages would be initialized from the plugin already and client would reuse the ones set on the server.
You inspired me to test something. With lazy: true
and empty file (export default {}
), the behavior changed to
// server
{ source: "nuxtConfig" }
{ source: "plugin" }
{ source: "nuxtServerInit" }
// client
{ source: "nuxtServerInit" }
{ source: "plugin" }
Which makes nuxt-i18n
see changes done in nuxtServerInit
on client-side. So I can have my parallel requests to translations 3rd party together with other requests in nuxtServerInit
.
Not sure what you mean because nuxtServerInit
doesn't run on the client.
I meant to set the messages from the file used for lazy loading.
It doesn't run on the server. I meant if I will do this:
// nuxt.config.js
modules: [
["nuxt-i18n", {
...,
locales: [
{
code: "en-GB",
}
],
vueI18n: {
...,
messages: {
"en-GB": {
"source": "nuxtConfig",
},
},
},
],
],
// store/index.js
nuxtServerInit ({ commit, dispatch }, context) {
this.$i18n.setLocaleMessage("en-GB", { "source": "nuxtServerInit" });
},
I will see text for $t("source") as nuxtServerInit
rendered on server, replaced by text nuxtConfig
on client. (messages changes in nuxtServerInit
are ignored)
But if I will do this:
// nuxt.config.js
modules: [
["nuxt-i18n", {
...,
locales: [
{
code: "en-GB",
file: "index.js"
}
],
lazy: true,
langDir: "locales/"
],
],
// locales/index.js
export default {
"en-GB": {
"source": "file",
}
}
// store/index.js
nuxtServerInit ({ commit, dispatch }, context) {
this.$i18n.setLocaleMessage("en-GB", { "source": "nuxtServerInit" });
},
I will see text for $t("source") as nuxtServerInit
rendered on server, replaced by same text nuxtServerInit
on client.
So it looks like the lazy:true
somehow consider changes done in nuxtServerInit
, which is not the case with lazy:false
.
The order of execution is
lazy: false
run nuxt-i18n plugin client
with the state of $i18n set on nuxt-i18n plugin server
, excluding changes done of $i18n in nuxtServerInit
. Which is not the case for lazy:true
.
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.
Closing this as v7 is not being actively worked on (critical hotfixes only), if this still applies to v8 and later please open a new issue!
Is your feature request related to a problem? Please describe.
In my project, I want to have the ability to host messages on an external server (Amazon S3 in my case) and fetch them on every page request, this way I would be able to update messages almost real-time without dependency on deploys. Also, I want to use git messages as a fallback (I'm doing it using
deepmerge
of git-based and cloud-based messages per locale)Describe the solution you'd like
Since I already have some requests in
nuxtServerInit
, I want to have a request to the external server there, to parallel my requests for performance reasons. But as for now, overwrite messages usingcontext.app.i18n.setLocaleMessage
get overwritten on the client, noted here: https://github.com/nuxt-community/i18n-module/issues/831 (Solution with hosting messages in nuxtStore would fit)Describe alternatives you've considered
I tried another way using lazy:true and having the same js file for all locales. In this file, I have a promise containing requests to the external server. Cons are: 1) this requests can't be parallel with
nuxtServerInit
2) these requests are sent again on the client