URL with URL-encoded characters like %23 gets decoded when changing locale
Environment
- Operating System: Linux
- Node Version: v18.18.0
- Nuxt Version: 3.11.2
- CLI Version: 3.11.1
- Nitro Version: 2.9.6
- Package Manager: [email protected]
- Builder: -
- User Config: devtools, modules, i18n, ssr
- Runtime Modules: @nuxtjs/[email protected]
- Build Modules: -
Reproduction
https://stackblitz.com/edit/i18n-url-encoding-issue?file=app.vue
Describe the bug
If an URL contains an URL-encoded character like "%23" and we switch the language, the url gets decoded and converted into a "#" which breaks for example the $route.params usage.
- Open Reproduction
- Click "Go to my-blog-post%23number1-someid" link
- Change locale
- Observe $route.params
Before locale change the route params are: (which vue-router already decodes correctly)
{ "slug": "my-blog-post#number1-someid" }
after locale change:
{ "slug": "my-blog-post" }
and we get a route hash
#number1-someid
You can also open the preview in a new tab to see the decoding in the URL bar.
The only other issue I found which could be maybe related to this is: https://github.com/nuxt-modules/i18n/issues/2698
Additional context
No response
Logs
No response
It's been a while back since I dived into debugging and figuring out a solution for #2698 but from what I remember the core cause of your issue is the same, I should probably update the issue description.
The module internally uses $router.resolve to retrieve the localized route based on the passed argument. In some cases the resolve function is used more than once with a previous resolved result, unfortunately doing so loses information:
const router = useRouter()
const arg = '/en/blog/my-blog-post%23number1-someid'
const resolved1 = router.resolve(arg)
const resolved2 = router.resolve(resolved1)
console.table({ arg, resolved1: resolved1.fullPath, resolved2: resolved2.fullPath })
Would result in this
| key | value |
|---|---|
| arg | /en/blog/my-blog-post%23number1-someid |
| resolved1 | /en/blog/my-blog-post%23number1-someid |
| resolved2 | /en/blog/my-blog-post#number1-someid |
I have some working concepts that deal with this issue from a while ago but they involve some larger changes to the routing logic, it will take time to test and see which solution makes most sense. So unfortunately I won't have a solution in the short term! Will let you know if I find any workarounds to use instead.
Kind a same issue here, where the output of localePath now containers %3F at the end.
@memic84
What are you passing to localePath?
@BobbieGoede my mistake, for reason a question mark was appended in the route name. Fixed and not a module issue.
Closing this as duplicate, let's keep tracking it here #2698