codeDragon
codeDragon

Reputation: 65

How to persist localisation in a vue app?

I am trying to build a multilingual Vue app with vue-i18n, and I am wondering how to persist the selected language? Anybody has experience with localisation? Is it possible by adding the language as a param to vue router? And or are there other ways ?

Upvotes: 4

Views: 1217

Answers (2)

Daniel Qolami
Daniel Qolami

Reputation: 1

This is what I did:

.env file:

# i18n
VITE_I18N_LOCALE=fa
VITE_I18N_FALLBACK_LOCALE=fa
VITE_LOCALSTORAGE_LOCALE=locale
VITE_SUPPORTED_LOCALES=en,fa

composable/useLocale.ts file:

  1. for initial locale (we will call this inside i18n file)
export function useInitialLanguage() {
  function isLocaleSupported(locale) {
    // since we use this function to start i18n, we don't have access to 
    // "availableLocales" of useI18n, so we need to specify locales in our .env file
    const supportedLocales = import.meta.env.VITE_SUPPORTED_LOCALES.split(",");
    return supportedLocales.includes(locale);
  }
  function getPersistedLocale() {
    const persistedLocale = localStorage.getItem(import.meta.env.VITE_LOCALSTORAGE_LOCALE);
    if (!persistedLocale) return null;

    if (!isLocaleSupported(persistedLocale)) {
      localStorage.removeItem(import.meta.env.VITE_LOCALSTORAGE_LOCALE);
      return null;
    }

    return persistedLocale;
  }
  function guessDefaultLocale() {
    const userPersistedLocale = getPersistedLocale();
    if(userPersistedLocale) {
      return userPersistedLocale;
    }

    ...

    // if no declared locale in localStorage or ...
    return import.meta.env.VITE_I18N_LOCALE || "en";
  }

  return { guessDefaultLocale };
}
  1. for getting the Locale or changing it:
export function useLanguage() {
  const { locale } = useI18n();
  ...
  const language = computed({
    get: () => locale.value,
    set: (lang) => {
      locale.value = lang;
      localStorage.setItem(import.meta.env.VITE_LOCALSTORAGE_LOCALE, lang);
    },
  });
  // to change the locale, write this in your components: useLanguage.language = "en"

  return { language, ... };
}

i18n.ts file:

import { createI18n } from 'vue-i18n';
import { useInitialLanguage } from "@/composables/useLanguage.js";

const { guessDefaultLocale } = useInitialLanguage();

export default createI18n({
  legacy: false, // Vuetify does not support the legacy mode of vue-i18n
  // legacy: false ---> to switch from legacy mode (options api) to composition api mode
  // reference https://vue-i18n.intlify.dev/guide/advanced/composition.html
  locale: guessDefaultLocale(),
  fallbackLocale: import.meta.env.VITE_I18N_FALLBACK_LOCALE || 'fa',
  messages: {
    "en": en,
    "fa": fa,
  },
});

Upvotes: 0

sulu00
sulu00

Reputation: 102

Each time you change/set the locale you need to store its value in the localStorage. Add this to your App:

watch: {
    '$i18n.locale': function(newVal, oldVal) {
        localStorage.setItem('last-locale', newVal)
     }
}

Then in the i18n.js initialization file read this value on startup:

export default createI18n({
  ...
  locale: getStartingLocale(),
  ...
})

And just add a function:

function getStartingLocale() {
    if (localStorage.getItem('last-locale')) {
        return localStorage.getItem('last-locale')
    }
    return process.env.VUE_APP_I18N_LOCALE || "en"
}

Upvotes: 5

Related Questions