1

I have a multilingual Vue (Nuxt) app. Based I'm setting the selected language / locale in the URL, e.g. http://www.example.net/sv-SE/somepage.

The routes are registered with an optional iso code: /:iso_code([a-z]{2}-[A-Z]{2})?/somepage. This all works as intented.

Now to my question: I have a language dropdown where the user can set the desired language. Is there any way to update the route param iso_code above, without resorting to history.replaceState?

I've tried the router API, without success. The URL isn't updated, i.e. if the URL is http://www.example.net/sv-SE/somepage, sv-SE isn't replaced with en-US when running the code:

this.$router.replace({ path: this.$route.fullPath, params: { iso_code: 'en-US' } })
Johan
  • 35,120
  • 54
  • 178
  • 293

1 Answers1

4

To push a route with the params object, you should use a named route:

const routes = [
  {
    path: '/:iso_code([a-z]{2}-[A-Z]{2})?/somepage',
    name: 'somepage',
    //...
  }
]
export default new VueRouter({ routes })

Then, you'd $router.push the route's name along with params:

App.vue:

<template>
  <div>
    <router-link :to="{ name: 'somepage', params: { iso_code: 'sv-SE' }}">sv-SE</router-link>

    <button @click="$router.push({ name: 'somepage', params: { iso_code: 'es-SP' }})">es-SP</button>
  </div>
</template>

demo of named route

Additionally, you could update the params of the current route by pushing only the params object (i.e., without a path or name). For example, assuming that path/name are already at the correct route to receive the iso_code parameter, you could $router.push({ params: { iso_code: 'es-SP' }}):

SomePage.vue:

<template>
  <div>
    <div>{{ iso_code }}</div>
    <button @click="$router.push({ params: { iso_code: 'es-SP' }})">es-SP</button>
  </div>
</template>

demo of params update for current route


If you preferred not to use named routes, you'd have to push the fully resolved path (e.g., /sv-SE/somepage) and no params:

this.$router.push('/sv-SE/somepage')

The disadvantage in this case is you'd have to update this reference if you ever decide to change the path.

tony19
  • 125,647
  • 18
  • 229
  • 307
  • Thanks, just noticed it also seems to work with only params? e.g. `this.$router.push({ params: { iso_code: 'sv-SE' } })` – Johan Feb 24 '20 at 00:46
  • Oh, nice. I wasn't aware that could be done. – tony19 Feb 24 '20 at 07:11
  • Does it still work? I'm using a rather old version of the router. If it does, please update the answer – Johan Feb 24 '20 at 07:46
  • @Johan It still works, but requires the current route to accept the `iso_code` param (i.e., the current route must be `somepage`). See updated answer. – tony19 Feb 24 '20 at 08:08