nuxt-modules / i18n

I18n module for Nuxt
https://i18n.nuxtjs.org
MIT License
1.75k stars 483 forks source link

Configured locales get overridden when installing @nuxtjs/i18n using Nuxt Kit's installModule utility #2874

Open benjamindedonder opened 7 months ago

benjamindedonder commented 7 months ago

Environment

Local environment:

Reproduction

https://stackblitz.com/edit/github-8ok7gy-kkmqkq

Describe the bug

I am adding new pages from my own module as documented here. I am installing and configuring @nuxtjs/i18n from my own module after I added these new pages as documented here.

The locales that I configured in the moduleOptions passed to the installModule function are not present in the locales of the i18n instance.

Additional context

Use case: I want to add and configure new pages in a headless CMS, I want to translate the routes and I want to configure these route translations in the headless CMS as well.

I debugged the issue to the applyLayerOptions function. This is where options.locales is overridden by mergedLocales.

When generating mergedLocales in the mergeLayerLocales function, I can see that options.locales is made sure not empty, but I don't see it being used after that since the mergeConfigLocales function does not consider options.

Logs

No response

BobbieGoede commented 7 months ago

Related https://github.com/nuxt-modules/i18n/issues/2809

benjamindedonder commented 7 months ago

It seemed to me that the @nuxtjs/i18n module did receive the options I passed with installModule, but options.locales got overridden with an empty array generated by mergeConfigLocales. I only debugged with the locales option in mind as for example the defaultLocale and strategy options I configured were working fine.

BobbieGoede commented 7 months ago

The main issue I have with supporting installModule is that I'm not sure how we can support multiple modules using installModule. I believe a module only gets installed once using this method, this is not a limitation for layers which ends up in an array of configurations.

So basically, I know we can support installModule, but from what I understand, it will start becoming an issue if a project has multiple modules that install @nuxtjs/i18n using installModule. It will only become noticeable when that happens (I could be misunderstanding the inner workings entirely, it's been a while since looking into it).

BobbieGoede commented 7 months ago

Here's a reproduction of what I'm thinking of is an issue: https://stackblitz.com/edit/github-a3adyq-gefcfu?file=nuxt.config.ts

benjamindedonder commented 7 months ago

Yes, you are right. When you use installModule multiple times, the module is only installed once with the options provided of the one instance that is used to install the module. This kind of makes sense to me. I don't know how you would work around that.

However, I don't think that issue is related to my issue here. I'm using installModule only once and so my provided options are available when installing the @nuxtjs/i18n module. My issue is that my configured locales get lost in the mergeLayerLocales function.

This issue already was reported in #2802 as well.

benjamindedonder commented 7 months ago

As suggested in #2802, the mergeConfigLocales function could accept the options as a parameter and include the already present options.locales in its result.

EDIT: Actually, I think I see the issue. I think this line needs to be changed from:

return mergeConfigLocales(configs)

to:

return mergeConfigLocales(configs, options.locales)
benjamindedonder commented 7 months ago

Hey, this issue is still present. I updated the StackBlitz reproduction to use @nuxtjs/i18n version 8.3.0.

BobbieGoede commented 7 months ago

Sorry about that, you're right, I'll have to change my fix to also take into account string locales (and object locales without files).

I noticed your other issue comment (https://github.com/nuxt-modules/i18n/issues/2873#issuecomment-2037385391) about using layers as a workaround for that issue, the same will work for this issue.

Even though installModule comes with its limitations I'll work on a solution for both issues,.

Yes, you are right. When you use installModule multiple times, the module is only installed once with the options provided of the one instance that is used to install the module. This kind of makes sense to me. I don't know how you would work around that.

I just want to clarify using installModule once in a project should work fine (at least, after I have resolved these issues) but will cause issues when any other module or any of their module dependencies try to do the same.

Only the options passed with the first call of installModule will be provided to the module and options passed by subsequent calls are ignored and the module has no way of retrieving these options (in contrast to those provided by layers).

benjamindedonder commented 7 months ago

I understand the issue with multiple installModule calls.

For my use case however, I don’t see another way around using installModule inside my own module, because I need to retrieve data from a headless CMS that I need to pass with the moduleOptions for @nuxtjs/i18n. Specifically, I am retrieving the available locales, the default locale, and route translations of some pages that are configured in the CMS and are not present in the Nuxt App.

So in my module I am retrieving this data, and then I’m adding those pages as described in my other issue. To reslove that issue, I’m now creating those page components in a separate Nuxt Layer, so that I can distinguish the pages from my CMS from the pages in my Nuxt App so that I can delete them as well. So my module is located in that separate Nuxt Layer, but then I still need to extend the moduleOptions for @nuxtjs/i18n with the available locales, the default locale, and those route translations.

I know there is a i18n:registerModule Nuxt Hook, but this is only to extend messages, so this does not work for me.

benjamindedonder commented 7 months ago

In any case, thank you for your help and quick replies! If this issue could be resolved, then everything is working fine for me for now. :)

SergkeiM commented 5 months ago

Having same issue

@benjamindedonder Did you found a solution for this until is fixed?

benjamindedonder commented 5 months ago

When I was having this issue, I didn't really have a workaround. I hard-coded the available locales inside nuxt.config.ts until the issue would be solved.

But in the end, I learned that it was possible to have an async Nuxt config. So this made it no longer necessary for me to fetch and register the extra pages and their translation information inside a separate module.

So now I am fetching the available locales, the default locale, and route translations of some extra pages inside nuxt.config.ts and I am adding this information to the module options of @nuxtjs/i18n in there.