[Vuejs]-How can I implement a multi-language switch in Nuxt?

0πŸ‘

Providing Different Routes for Language Switching

So your main question is not about how to switch languages, but rather about how to load different components when the language parameter in the route changes.

If you insist on showing the language in the URL, you need to clarify this in Vue Router as well. Your main route will only be /:lang, which allows you to include the language in every sub-route. Your actual pages will be sub-routes of this. You will need to import the components dynamically, using the :lang variable and the appropriate file path that corresponds to your own file structure.

Here’s an example of how to implement this approach:

/**
 ** Get Component
 */
const getComponentByLang = (resolve, route, componentPath) => {
  const lang = route.params.lang;
  return import(`./pages/${lang}/${componentPath}.vue`).then((component) => {
    resolve(component);
  });
};

/**
 ** Routes
 */
const routes: [
  // Main Route (/es or /en ...)
  {
    path: '/:lang',
    children: [
      // Sub Route (/es/articles/title or /en/articles/title ...)
      // Load /langFolder/Articles/Show.vue
      {
        path: '/articles/:name',
        component: (resolve, route) => getComponentByLang(resolve, route, 'Articles/Show')
      },
      // Sub Route (/es/topics/title or /en/topics/title ...)
      // Load /langFolder/Topics/Index.vue
      {
        path: '/topics/:name',
        component: (resolve, route) => getComponentByLang(resolve, route, 'Topics/Index')
      }
    ],
  },
];

More informations:

Nested Routes on Vue-Router

Lazy Component Loading on Vue-Router


It is necessary to place every component in its own language folder, including the English one.

# normal directory tree
server
β”œβ”€β”€ your-project
β”‚   β”œβ”€β”€ pages
β”‚   β”‚   β”œβ”€β”€ en
β”‚   β”‚   β”‚   β”œβ”€β”€ index.vue
β”‚   β”‚   β”‚   └── somepage.vue
β”‚   β”‚   └── es
β”‚   β”‚       β”œβ”€β”€ index.vue
β”‚   β”‚       └── somepage.vue
β”‚   β”œβ”€β”€ ...
const getComponentByLang = (resolve, route, componentPath) => {
  const lang = route.params.lang;
  return import(`./pages/${lang}/${componentPath}.vue`).then((component) => {
    resolve(component);
  });
};

Alternatively, you can declare the English language as an exception when defining the component’s path.

# normal directory tree
server
β”œβ”€β”€ your-project
β”‚   β”œβ”€β”€ pages
β”‚   β”‚   β”œβ”€β”€ index.vue
β”‚   β”‚   β”œβ”€β”€ somepage.vue
β”‚   β”‚   └── es
β”‚   β”‚       β”œβ”€β”€ index.vue
β”‚   β”‚       └── somepage.vue
β”‚   β”œβ”€β”€ ...
const getComponentByLang = (resolve, route) => {
  const lang = route.params.lang;
  const path = lang === 'en' ? `./pages/${componentPath}.vue` : `./pages/${lang}/${componentPath}.vue`
  return import(path).then((component) => {
    resolve(component);
  });
};


Language selection in both cases

In broad strokes… You need an array listing the selectable languages. Then, you create a dropdown menu where you populate the options from that array. Upon value change in the dropdown, you invoke a language selection function. Assuming you have translations for ALL your pages, within this function, you’ll replace the "language" part of the current URL with the selected language. So, for instance, if the current URL is example.com/en/articles/mycurrenttitle, after selecting a new language, the URL will become example.com/es/articles/mycurrenttitle.

<template>
  <div>
    <label for="language">Select Language:</label>
    <select id="language" v-model="selectedLanguage" @change="changeLanguage">
      <option v-for="language in languages" :value="language.value" :key="language.value">{{ language.label }}</option>
    </select>

    <p>Current URL: {{ currentUrl }}</p>
    <p>Selected Language: {{ selectedLanguage }}</p>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import { useRouter, useRoute } from 'vue-router';

const languages = ref([
  { label: 'English', value: 'en' },
  { label: 'EspaΓ±ol', value: 'es' }
]);
const selectedLanguage = ref('');
const currentUrl = ref('');

const router = useRouter();
const route = useRoute();

const changeLanguage = () => {
  if (selectedLanguage.value) {
    const newUrl = route.path.replace(/^\/(en|es)/, `/${selectedLanguage.value}`);
    router.push(newUrl);
  }
};

onMounted(() => {
  currentUrl.value = route.path;
  const langMatch = currentUrl.value.match(/^\/(en|es)/);
  selectedLanguage.value = langMatch ? langMatch[1] : '';
});
</script>
πŸ‘€rozsazoltan

-1πŸ‘

use vue-multilanguage plugin
for reference check here
https://www.npmjs.com/package/vue-multilanguage

πŸ‘€Dhara Bhalala

Leave a comment