SoFunction
Updated on 2025-04-13

Vue3 Access i18n Realizes International Multilingual Case Analysis

1. Basic Methods

In 3, the most commonly used package isvue-i18n, usually we will havevue-i18n-routingUse together.

vue-i18nResponsible for rendering text placeholders according to the language of the current page, for example:

<span>{{ t('Login') }}</span>

When the language is set to Chinese, theLoginRendered as "Login".

vue-i18n-routingResponsible for binding the page language to the URL, for example:

/zh-CN/repo

Indicates access to the Chinese version/repoPath.

Putting web pages in different languages ​​under different URLs helps SEO because it can be found in<head>Add language information in part to increase the probability that different languages ​​are indexed by search engines.

Google's crawling mechanism for multilingual Vue sites is as follows:

  • JS dynamic pages similar to Vue sites can be crawled without affecting weights (seeGoogle SEO)。
  • Pages that match the user's preferred language will be displayed first (seeGoogle SEO)。

2. Basic implementation

The first step is to install a Vite to use it<i18n>Tag plugin:unplugin-vue-i18n

Then adjust

import { fileURLToPath, URL } from 'node:url';
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import VueDevTools from 'vite-plugin-vue-devtools';
import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite';
export default defineConfig({
  plugins: [
    vue(),
    VueDevTools(),
    VueI18nPlugin({}),
  ],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', )),
    },
  },
});

After adding plug-ins, we can use them within the components<i18n>piece:

&lt;script setup lang="ts"&gt;
import { useI18n } from 'vue-i18n';
const { t, locale } = useI18n({ inheritLocale: true, useScope: 'local' });
&lt;/script&gt;
&lt;template&gt;
  &lt;span&gt;{{ t('Login') }}&lt;/span&gt;
&lt;/template&gt;
&lt;i18n lang="yaml"&gt;
en:
  Login: 'Login to web'
zh-CN:
  Login: 'Log in'
&lt;/i18n&gt;

Here we define two different languages.

3. Path binding

Next, we need to define the use of URL as the current language, editrouter/

import { createRouter as _createRouter, type RouteLocationNormalized } from 'vue-i18n-routing';
import { createWebHistory } from 'vue-router';
import HomeView from '@/views/';
const locales = [
  {
    code: 'en',
    iso: 'en-US',
    name: 'English',
  },
  {
    code: 'zh-CN',
    iso: 'zh-CN',
    name: 'Chinese',
  },
];
export function createRouter(i18n: any) {
  const router = _createRouter(i18n, {
    version: 4,
    locales: locales,
    defaultLocale: 'zh-CN',
    history: createWebHistory(.BASE_URL),
    routes: [
      {
        path: '/home',
        name: 'home',
        component: HomeView,
      },
    ],
  });
  return router;
}

We define the supported language types and add the originalroutesPackage it,vue-i18n-routingAll supported languages ​​will be automatically generatedroutes

  • /home= Chinese
  • /en/home= English

Since we set it updefaultLocale: 'zh-CN', the default path is Chinese.

Then we need to add the part of the source code that involves jumping, for example:

({ name: 'home' });

Add alllocalePath, indicates that it is the URL path of the current language:

import { useLocalePath } from 'vue-i18n-routing';
const localePath = useLocalePath();
(localePath({ name: 'home' }));

This completes the path binding.

4. Automatic switch

Sometimes, we want no default language, but automatically select based on the user's browser language:

  • /zh-CN/home= Chinese
  • /en/home= English
  • /home-> Redirect (browser preference Chinese) ->/zh-CN/home= Chinese
  • /home-> Redirect (browser preference English) ->/en/home= English

At this time, we need to define a store, and use Pinia store here, Vuex is the same.

import { usePreferredLanguages, useStorage } from '@vueuse/core';
import { defineStore } from 'pinia';
export const useLangStore = defineStore('lang', {
  state: () => {
    const savedLang = useStorage<string | null>('lang', null, undefined);
    const systemLang = usePreferredLanguages();
    return { savedLang, systemLang };
  },
  getters: {
    lang: (state) => {
      const lang =  || [0];
      if (('zh')) {
        return 'zh-CN';
      } else {
        return 'en';
      }
    },
  },
  actions: {
    setLang(l?: string) {
      if (!l) {
         = null;
      } else {
         = l;
      }
    },
  }
});

This code uses theusePreferredLanguagesTo obtain the browser language preferred by users and useuseStorageAdded a storage item in LocalStorage.

The logic is: if the user manually sets the language (savedLang), then use it; if not, use the first language preferred by the system. In this way, we just need to takelangThe value of   can get the final preferred language whether it is Chinese or English.

Then we need to define a path guard to automatically handle situations where there is no language in the URL.

import { createRouter as _createRouter, type RouteLocationNormalized } from 'vue-i18n-routing';
import { createWebHistory } from 'vue-router';
import HomeView from '@/views/';
const locales = [
  {
    code: 'en',
    iso: 'en-US',
    name: 'English',
  },
  {
    code: 'zh-CN',
    iso: 'zh-CN',
    name: 'Chinese',
  },
  {
    code: '',
    iso: '',
    name: '',
  }
];
export function createRouter(i18n: any) {
  const router = _createRouter(i18n, {
    version: 4,
    locales: locales,
    history: createWebHistory(.BASE_URL),
    routes: [
      {
        path: '/home',
        name: 'home',
        component: HomeView,
      },
    ],
  });
  ((to: RouteLocationNormalized, from: RouteLocationNormalized) =&gt; {
    const lang = useLangStore();
    const pathLocale = ('/')[1];
    if ((!pathLocale) || (!(locale =&gt;  === pathLocale))) {
      return `/${}${}`;
    }
  });
  return router;
}

There are three things to note here:

  • We have added a new spacelocales, so that the request can be reached
  • We've removed itdefaultLocale
  • Use the store you just defined:useLangStore()This line of code must be placed, and cannot be placed at the top of the module, because Pinia has not started yet when loading the module.

In this way, the languageless path automatically jumps to the current preferred language path.

5. Navigation bar toggle button

Then, you can add a button to the navigation bar to manually switch languages, for example:

&lt;script setup lang="ts"&gt;
import { useLocalePath, useSwitchLocalePath } from 'vue-i18n-routing';
import { useLangStore } from '@/stores/lang';
const lang = useLangStore();
const { t, locale } = useI18n({ inheritLocale: true, useScope: 'local' });
&lt;/script&gt;
&lt;template&gt;
&lt;div
  @click="
    ('en');
    (switchLocalePath('en'));
    menuShown = '';
  "
  class="py-2 px-2 gap-2 flex items-center cursor-pointer hover:bg-slate-400/10"
  :class="{ 'text-sky-300': locale == 'en' }"
  role="option"
  tabindex="-1"
  :aria-selected="locale == 'en'"
&gt;
  &lt;IconEnglish class="w-5 h-5 text-slate-400 dark:text-slate-200" /&gt;
  English
&lt;/div&gt;
&lt;div
  @click="
    ('zh-CN');
    (switchLocalePath('zh-CN'));
    menuShown = '';
  "
  class="py-2 px-2 gap-2 flex items-center cursor-pointer hover:bg-slate-400/10"
  :class="{ 'text-sky-300': locale == 'zh-CN' }"
  role="option"
  tabindex="-1"
  :aria-selected="locale == 'zh-CN'"
&gt;
  &lt;IconChinese class="w-5 h-5 text-slate-400 dark:text-slate-200" /&gt;
  Chinese
&lt;/div&gt;
&lt;/template&gt;

Here, we store the currently manually set language in the store we just defined, and useswitchLocalePathTo realize path and language switching.

6. SEO and Head Meta

Different language versions of the same content should be inheadmark it in   and point to all other alternative pages (seeGoogle SEO). Here we canUsed in ChinauseLocaleHeadand from@unhead/vuePackeduseHeadMake settings:

import { useLocaleHead } from 'vue-i18n-routing';
import { useHead } from '@unhead/vue';
const i18nHead = useLocaleHead({ addSeoAttributes: true, defaultLocale: null, strategy: null });
onMounted(() => {
  useHead({
    htmlAttrs: computed(() => ({
      lang: !.lang,
    })),
    link: computed(() => [...( || [])]),
    meta: computed(() => [...( || [])]),
  });
});

This basically realizes a multilingual international site. It may be that while front-end translation, the back-end also needs to be translated. Please look forward to the next issue: How to connect to i18n on the Python Flask back-end to achieve international multilingualization!

7. Case Analysis

Case:The front-end interface is internationalized multilingual, and is implemented using the methods described in this article. You can see the effect.

Everyone is also welcome to useMutual praise platform to increase the visibility of your open source projects and gain more users.

This is the article about how to connect to Vue3 to i18n to achieve international multilingualization. For more relevant Vue3 international multilingual content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!