How to build multilingual Vue.js application

Creating a suitable Vue.js sample to try out Gitloc

If you want to create your project from scratch, then you can use the following step-by-step guide, where we will create a multilingual Vue.js sample project using i18next and Gitloc

Create a Vue Application (more at


  • Familiarity with the command line

  • Install Node.js version 16.0 or higher

In this section we will introduce how to scaffold a Vue Single Page Application on your local machine. The created project will be using a build setup based on Vite and allow us to use Vue Single-File Components (SFCs).

Make sure you have an up-to-date version of Node.js installed, then run the following command in your command line:

npm init vue@latest

This command will install and execute create-vue, the official Vue project scaffolding tool. You will be presented with prompts for several optional features such as TypeScript and testing support:

✔ Project name: … <your-project-name>
✔ Add TypeScript? … No / Yes
✔ Add JSX Support? … No / Yes
✔ Add Vue Router for Single Page Application development? … No / Yes
✔ Add Pinia for state management? … No / Yes
✔ Add Vitest for Unit testing? … No / Yes
✔ Add Cypress for both Unit and End-to-End testing? … No / Yes
✔ Add ESLint for code quality? … No / Yes
✔ Add Prettier for code formatting? … No / Yes

Scaffolding project in ./<your-project-name>...

If you are unsure about an option, simply choose No by hitting enter for now. Once the project is created, follow the instructions to install dependencies and start the dev server:

cd <your-project-name>
npm install
npm run dev

You should now have your first Vue project running! Note that the example components in the generated project are written using the Composition API and <script setup>, rather than the Options API. Here are some additional tips:

When you are ready to ship your app to production, run the following:

npm run build

This will create a production-ready build of your app in the project's ./dist directory. Check out the Production Deployment Guide to learn more about shipping your app to production.

Setup i18next (more at and

In our example, we will create a project with 2 languages and separate files for translations.

Install some i18next dependencies:

npm install i18next i18next-vue i18next-browser-languagedetector i18next-http-backend

Add i18n.js file to the repository:

import i18next from 'i18next'
import I18NextVue from 'i18next-vue'
import LanguageDetector from 'i18next-browser-languagedetector'
import Backend from 'i18next-http-backend'

  // i18next-http-backend
  // loads translations from your server
  // detect user language
  // learn more:
  // init i18next
  // for all options read:
    debug: true,
    languages: ['en', 'de'],
    fallbackLng: 'en',
    ns: ['common', 'welcome'],
    defaultNS: 'common',

export default function (app) {
  app.use(I18NextVue, { i18next })
  return app

Import this file in our main.js file:

import { createApp } from 'vue'
import i18n from '../i18n'
import App from './App.vue'


Place translations into dedicated .json files in the public folder:

└── public
    └── locales
        ├── de
        │   ├── common.json
        │   └── welcome.json
        └── en
            ├── common.json
            └── welcome.json

Now define a language switcher component:

    <div v-if="languages">
      <span v-for="(lng, index) in Object.keys(languages)" :key="lng">
        <a v-if="$i18next.resolvedLanguage !== lng" v-on:click="$i18next.changeLanguage(lng)">
          {{ languages[lng].nativeName }}
        <strong v-if="$i18next.resolvedLanguage === lng">
          {{ languages[lng].nativeName }}
        <span v-if="index < Object.keys(languages).length - 1">&nbsp;|&nbsp;</span>

export default {
  name: 'Language switcher',
  data() {
    return {
      languages: {
        en: { nativeName: 'English' },
        de: { nativeName: 'Deutsch' },

Add translations usage (more at and

For the first text we just use a simple test key to directly invoke the $t function. The $t is more or less the same as i18next.t.

<h1>{{ $t('test') }}</h1>
  "test": "Test"

For the second text we will use the attribute bindings withtitle key form welcome namespace.

<HelloWorld :msg="$t('welcome:title')" />
<script setup>
  msg: {
    type: String,
    required: true,

  <h1 class="green">{{ msg }}</h1>
  "title": "GitLoc example"

For the third text, we will interpolate subtitle key form welcome namespace by using the <i18next> component and named slots. These can be referenced as {someSlot} in the translations

<i18next :translation="$t('welcome:subtitle')">
  <template #vite>
    <a href="" target="_blank" rel="noopener">Vite</a>
  <template #vue>
    <a href="" target="_blank" rel="noopener">Vue 3</a>
  "subtitle": "You’ve successfully created a project with {vite} + {vue}."

Finally, сonnect your local project folder to your new repository on GitHub.

Done! Now you can move to the next step - connect remote repository to Gitloc

Last updated