Jip Helsen
Jip Helsen

Reputation: 1356

Changing a parameter in Vue 3 router

I was trying to change a route parameter with Vue router. My route is the following :

/document/:id?/:lang?/edit

Id and lang (language) are the parameters. I want to change the parameter lang using JavaScript without altering the rest of the route. I tried applying the following solution (found here). The solution was made for Vue 2 and not 3. So I tried to make an updated version. This is my code :

let params = this.$route.params
params.lang = 'en'
this.$router.push({params:params})
When I execute my code, there is no change in the route parameters nor an error logged in the console. Does anyone know a solution to this problem in Vue 3.

Thanks in advance.

Upvotes: 2

Views: 4605

Answers (2)

agm1984
agm1984

Reputation: 17160

I did it like this in Vue 3 with vue-i18n V9:

/src/i18n/index.js

import { createI18n } from 'vue-i18n';
import en from './en.json';
import es from './es.json';

const i18n = createI18n({
    locale: 'en',
    fallbackLocale: 'en',
    messages: {
        en,
        es,
    },
    sync: true,
    legacy: false,
    globalInjection: true,
});

export default i18n;

/src/components/LocaleSwitcher.vue

import i18n from '@/i18n';

...

watch(() => i18n.global.locale.value, () => {
    router.replace({
        name: route.name,
        params: {
            lang: i18n.global.locale.value,
        },
    });
});

/src/router/index.js

const routes = [
    {
        path: '/',
        redirect: 'lang'
    },
    {
        path: '/:lang',
        name: 'lang',
        component: HomePage,
    },
    {
        path: '/:lang/content/:contentId',
        name: 'guide.content',
        component: () => import('@/views/ContentRoot.vue'),
        children: [
            {
                path: '',
                name: 'guide.content.root',
                component: ContentPage,
            },
            {
                path: 'video',
                name: 'guide.content.video',
                component: ShowVideo,
            },
        ],
    },
    {
        path: '/:catchAll(.*)',
        component: () => import('@/views/404.vue'),
        hidden: true,
    },
];

router.beforeEach((to, from, next) => {
    const locale = to.params.lang; // Retrieve the current locale set in the URL

    // Check if the locale the user is trying to access is authorized.
    // In a larger application that supports lots of languages, you may want to store
    // all the locales in a separate array
    if (!['en', 'es'].includes(locale)) {
        return next(i18n.global.locale.value);
    }

    // Changing the language from the URL (either manually or with a link) is possible this way
    i18n.global.locale.value = locale;

    return next();
});

Upvotes: 0

Amirhossein Shahbazi
Amirhossein Shahbazi

Reputation: 1111

It's a bad way to change your route parameter like this.

Instead, replace your route with the same name, same id, but different lang:

  this.$router.replace({
    name: this.$route.name,
    params: {
      id: this.$route.params.id,
      lang: 'en' // or whatever you want
    }
  })

Don't forget to watch for the route changes if needed:

  watch: {
    $route(to, from) {
      // if anything needs to be done when the route changes
    }
  }

Upvotes: 4

Related Questions