nuxt-modules / i18n

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

useRoute('login') does not work, it expects useRoute('login__LOCALE') #2976

Open martinszeltins opened 3 months ago

martinszeltins commented 3 months ago

Environment

N/A

Reproduction

N/A

Describe the bug

Nuxt i18n module has support for Nuxt typedPages but I can't understand how to use it.

Nuxt docs says:

You can get typed params within a page by using const route = useRoute('route-name')

But I don't have one route-name when using i18n. I don't have a login route. Instead I have login__en, login__de, login__fr etc.

Passing in simply "login" does not work useRoute('login'), it expects a locale which is very strange. How do I use this? I couldn't find anything in the docs.

Additional context

No response

Logs

No response

martijndewit commented 3 months ago
definePageMeta({
      name: 'login'
    })

on the login page

So you can use 'name' as localeRoute({ name: 'login' }, locale.value) for example.

martinszeltins commented 3 months ago

@martijndewit That didn't work. I still see index__en and user__de in route names.

image

image

martijndewit commented 3 months ago

How did you set your Routing Strategy ?

martinszeltins commented 3 months ago

Sorry, that still doesn't work. useRoute() expects a union type to be passed in. I don't think the routing strategy has anything to do with it.

Error:

Argument of type '(RouteLocation & { href: string; }) | undefined' is not assignable to parameter of type 'keyof RouteNamedMap | undefined'.

image

github-actions[bot] commented 3 months ago

Would you be able to provide a reproduction? 🙏

More info ### Why do I need to provide a reproduction? Reproductions make it possible for us to triage and fix issues quickly with a relatively small team. It helps us discover the source of the problem, and also can reveal assumptions you or we might be making. ### What will happen? If you've provided a reproduction, we'll remove the label and try to reproduce the issue. If we can, we'll mark it as a bug and prioritise it based on its severity and how many people we think it might affect. If `needs reproduction` labeled issues don't receive any substantial activity (e.g., new comments featuring a reproduction link), we'll close them. That's not because we don't care! At any point, feel free to comment with a reproduction and we'll reopen it. ### How can I create a reproduction? We have a couple of templates for starting with a minimal reproduction: 👉 [Reproduction starter (v8 and higher)](https://stackblitz.com/fork/github/BobbieGoede/nuxt-i18n-starter/tree/v8) 👉 [Reproduction starter (edge)](https://stackblitz.com/fork/github/BobbieGoede/nuxt-i18n-starter/tree/edge) A public GitHub repository is also perfect. 👌 Please ensure that the reproduction is as **minimal** as possible. See more details [in our guide](https://nuxt.com/docs/community/reporting-bugs/#create-a-minimal-reproduction). You might also find these other articles interesting and/or helpful: - [The Importance of Reproductions](https://antfu.me/posts/why-reproductions-are-required) - [How to Generate a Minimal, Complete, and Verifiable Example](https://stackoverflow.com/help/mcve)
MinecraftStorage1 commented 3 months ago

Same issue, why route names are localized by default? It makes code extremely unreadable and quite doesn't make sense. Every time I need to resolve a route path, I need to figure out the current locale and then suffix it with that locale. I think you should be able to just reference the route name without a locale, and it resolves into a path with the current locale.

letoast commented 2 months ago

How do you reproduce this with stackblitz? As far as I've tried there are no type hints on stackblitz with nuxt(vue). Not only that, I can't even get i18n to redirect to /en on stackblitz

https://stackblitz.com/edit/github-zep9gz-2odmdq?file=pages%2Ftest.vue

BobbieGoede commented 2 months ago

This is related to route strategy, you will not have this behavior when using no_prefix. Basically when using any other strategy the i18n module will generate localized routes and 'remove' original (unprefixed) routes when they should not exist.

We try to make this behavior easier to deal with by providing composables such as useLocalePath, useLocaleRoute etc. Unfortunately we have little control over the route type generation, it simply generates types based on the resulting routes, which are accurate for the usual useRoute composable but not useful for the composables we provide.

letoast commented 2 months ago

@BobbieGoede So how do you get type support with useLocaleRoute if for example you have a page in /pages/foo/[slug].vue?

image

...

image

Only this works, but nowhere did I get any hints that slug is even a possible key of params...

image

There are also no type hints that /:slug(.*)* is a possible route, even though I have [...slug].vue in my pages dir.

image

I'm guessing that this example is not even possible if you have strategy: 'prefix' set, because there's no way 'blog' would be a possible type hint https://i18n.nuxtjs.org/docs/api#uselocaleroute

<script setup>
const localeRoute = useLocaleRoute()
const { locale } = useI18n()
const linkPath = computed(() => {
  const route = localeRoute('blog', locale.value)
  return route != null ? route.path : '/'
})
</script>
BobbieGoede commented 2 months ago

I spent some time in the past week to see what it would take to have most of the type inference for these route composables/functions.

Here's what I have so far https://github.com/BobbieGoede/i18n/pull/49, this branch contains lots of duplicated code from both Vue Router and Nuxt, and relies on their internals so it's not anywhere close to being stable..

I will check with their maintainers at some point and see if I could make something happen for v9 but I'm not very optimistic that this is something they want to support/expose downstream.

martinszeltins commented 2 months ago

The only way that I've found to be able to get IDE autocomplete for route params is to use one of the locale like this

const route = useRoute('login___en')

route.params.id // autocomplete works now
Shhu commented 2 weeks ago

I am using this as a workaround, but it would be great not to have to.

const localeRoute = useLocaleRoute()
localeRoute({ name: 'users.edit' as 'users.edit___en', params: { id: row.id } })