nuxt-modules / i18n

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

Clear way to re-use the component of the matched page when language switching causes a navigation to a different locale prefix #2853

Open danwithabox opened 8 months ago

danwithabox commented 8 months ago

Describe the feature

I wish to keep page state when a language switcher causes the URL to change.

Currently, out-of-the-box, the URL change causes a component re-render. I would have guessed Vue router's goal of re-using and updating components when possible would apply, since the pages are the same, only the locale have changed. Instead, a console log on onMounted shows that a fresh component is mounted.

Is this intended behaviour? It seems counter-intuitive to me, but I have not found documentation nor issues about.

I tried a quick workaround (in pages/index.ts):

<script setup lang="ts">
definePageMeta({
    key: (route) => route.name.split("___")[0],
});
</script>

This works, since the postfixed pathnames seem to use a ___ separator, e.g.:

index___en-US
index___en-US___default
index___en-GB

With some more digging around, I changed the code to make it less hacky by avoiding the magic string ___:

<script setup lang="ts">
definePageMeta({
    key: (route) => {
        const key: string = useRouteBaseName()(route) ?? route.fullPath;
        return key;
    },
});
</script>

I am definitely not sure that this is the best way to achieve what I want. Could we have a dedicated option for this, or at least an official snippet in the documentation?

Additional information

Final checks

danwithabox commented 8 months ago

I tried to double-check the documentation for any snippets or info I might've missed on this, but at the time of writing the documentation is broken.

BobbieGoede commented 8 months ago

I tried to double-check the documentation for any snippets or info I might've missed on this, but at the time of writing the documentation is broken.

Sorry about that, the documentation was broken yesterday but it should be working again!

Is this intended behaviour? It seems counter-intuitive to me, but I have not found documentation nor issues about.

This is intended behaviour, when switching between languages you're essentially navigating to a different page with the same behaviour as you normally would experience. I think using a no_prefix routing strategy would work around this, but that would come with its own SEO implications.

Could you create a reproduction to show an example of page state that is lost/re-rendered?

danwithabox commented 7 months ago

Minimal example: https://github.com/danwithabox/issue_nuxt-modules-i18n_2853

After clone, npm start, out-of-the-box it will run without the definePageMeta workaround.

Should see 3 things:

Without the workaround:

To enable the workaround, uncomment key: i18n_pageKey, at /pages/index.vue:L10 ⚠️ and reload the page, as HMR doesn't effect this ⚠️ because of how definePageMeta is processed, which is also the reason why it can't be programmatically changed, but that's possibly not needed anyway.

With the workaround enabled:

This behavior is what I would prefer in most cases, because

I do like the granularity of specifying on which pages I want to have either behavior, via the key prop in definePageMeta. I do agree that the current default can be intended behaviour, but not the only intended behaviour. I'm fine with specifying it for every page, but some people may want a global config, not sure.

I'd love an importable utility like i18n_pageKey() in my example, or even just an official code snippet in the documentation. Any other solution is welcome too, as long as it's a canonical solution that I don't have to worry about being broken by an update.

BobbieGoede commented 7 months ago

@danwithabox I think your reproduction repo is private, I can't access it 😅

danwithabox commented 7 months ago

Indeed, I knew I forgot something! Should be good now, cheers 🫠

kazupon commented 7 months ago

Closing due to inactivity. Please open a new issue with a reference to this one if you can follow up with more information.

Thanks!

danwithabox commented 7 months ago

I will risk it and ping @BobbieGoede, I don't think this issue should be closed before input from you, maybe I should've pinged when I made my repo public 🤷‍♂️

I don't think opening a new issue just to bump this would be appreciated. And I can't really "follow up with more information" until some reaction to my repro / example 😅

BobbieGoede commented 7 months ago

Ah I did somehow forget to check this out again, the ping was necessary 😅..

I still have to give it a thorough look, I understand the benefits of not mounting the page again but we should consider what could be possible drawbacks as well.

There's been a few PRs with feature proposals that also touch on some core features that could have some overlap with each other including this, I'll reopen this and assign myself so we can keep the discussion open and I will look into it when I have more time 😥.