DEV Community

Cover image for Vue3 + i18n (bonus i18n ally)
NEIWAD
NEIWAD

Posted on

Vue3 + i18n (bonus i18n ally)

How to configure i18n and vue3 so that at the end of the project the translation files are not 10000 lines long and incomprehensible.

The solution? i18n namespaced files and the i18n ally extension!

1. Create a brand new project

pnpm create vue@latest
Enter fullscreen mode Exit fullscreen mode
✔ Project name: … vue3-i18n
✔ Add TypeScript? … Yes
✔ Add JSX Support? … No
✔ Add Vue Router for Single Page Application development? … No
✔ Add Pinia for state management? … No
✔ Add Vitest for Unit Testing? … No
✔ Add an End-to-End Testing Solution? › No
✔ Add ESLint for code quality? … No
✔ Add Prettier for code formatting? … No
Enter fullscreen mode Exit fullscreen mode
pnpm install && pnpm run dev
Enter fullscreen mode Exit fullscreen mode

You should now bet able to see a basic Vue3 project on localhost:5173

2. i18n

Install i18n for Vue3

pnpm install vue-i18n@9
Enter fullscreen mode Exit fullscreen mode

Create some translation files

Here is my architecture. Follow it for this tutorial, you can change it later with some job.

i18n files architecture

locales/en/auth.json

{
  "SignIn": "Sign In",
  "SignUp": "Sign Up"
}
Enter fullscreen mode Exit fullscreen mode

locales/en/commons.json

{
  "height": "Height",
  "weight": "Weight"
}
Enter fullscreen mode Exit fullscreen mode

For the FR part, I let you translate by yourself!

Init i18n configuration file

Inside locales folder create an index.ts file.

import { createI18n, type I18n, type Locale } from "vue-i18n";
import authEN from "./en/auth.json";
import authFR from "./fr/auth.json";
import commonsEN from "./en/commons.json";
import commonsFR from "./fr/commons.json";

let i18n: I18n;

const init = () => {
  i18n = createI18n({
    locale: "en",
    messages: {
      en: {
        auth: authEN,
        commons: commonsEN,
      },
      fr: {
        auth: authFR,
        commons: commonsFR,
      },
    },
  });
};

const setLocale = (locale: Locale): void => {
  i18n.global.locale = locale;
};

init();

export { i18n, setLocale };
Enter fullscreen mode Exit fullscreen mode

Add i18n to the Vue3 app

inside the main.ts import i18n as

import { i18n } from "./locales";
Enter fullscreen mode Exit fullscreen mode

And the use this i18n

createApp(App).use(i18n).mount("#app");
Enter fullscreen mode Exit fullscreen mode

3. Test our integration

Replace the content of App.vue with

<script setup lang="ts">
  import {setLocale} from "./locales"
  const changeLocale = () => {
    setLocale('fr')
  }
</script>

<template>
  <main>
    {{$t('auth.SignIn')}}
    {{$t('commons.height')}}
    <button @click=changeLocale>Change Locale</button>
  </main>
</template>
Enter fullscreen mode Exit fullscreen mode

You should see:

integration testing

And if you click on the button... TADA! Strings are no FR ones.

4. Bonus: i18n ally

Dealing with a large set of locales and translation can be such a pain in the a$$.

This is where the i18n ally extension come to the rescue.

i18n ally installation

You can add it to VSCode from the embeded marketplace or from this link

i18n ally configuration

Open User Settings Preferences (JSON) from the quick access shortcut.

shift + cmd + p
Enter fullscreen mode Exit fullscreen mode

And the add in the end of the JSON file these lines

  "i18n-ally.dirStructure": "auto",
  "i18n-ally.enabledFrameworks": ["vue"],
  "i18n-ally.enabledParsers": ["json", "yaml"],
  "i18n-ally.extract.autoDetect": true,
  "i18n-ally.namespace": true,
  "i18n-ally.pathMatcher": "{locale}/{namespaces}.json",
Enter fullscreen mode Exit fullscreen mode

i18n ally usage

When i18n ally is installed and configured in VSCode, you can open it from the sidebar button.

i18n ally

I let you play with this useful extension, but with it you can auto translate your string, create keys and see you translation coverage.

Links

vue3
vue-i18n-next
i18n-ally

Questions?

If you have some questions or issues, please share it with me in a comment, I will take a look at it quickly :)

Ciao

Top comments (1)

Collapse
 
thomasbnt profile image
Thomas Bnt ☕

Oh cool extension!