[how to] Implement i18next in quasar



  • Hello all

    I recently implemented i18next in my Quasar project.
    Here I will try to show you all how it was done.

    My use case

    The project is a multi language static site.
    I have a simple button with a popover to select languages.
    My language files go in ‘/src/statics/i18n/’ folder.
    I am using these packages: i18next, vue-i18next, i18next-xhr-backend

    Getting started

    Install basic packages
      $  npm install --save i18next  @panter/vue-i18next
    

    This will install the core i18next library, as well as the vue-i18next plugin.

    Boot up i18next

    
    // src/main.js
    
    // import libraries
    import i18next from 'i18next'
    import VueI18Next from '@panter/vue-i18next'
    
    ....
    
    // init i18next
    i18next
      .init({
        debug: false, // set this to true for now. Will give som interesting output in console
        lng: 'en', // default language
        resources: {  // fixed resources for now. may be useful to keep critical messages here. 
          en: { // language
            translations: { // Namespace. Default namespace is 'translations'
              key: 'value'  // your translations go here.
            }
          }
        }
      }, (err, t) => {
        if (DEV && err) {
          // if there is an error on init, log it
          console.log(err)
        }
      })
    
    // plug Vuei18Next into Vue,
    Vue.use(VueI18Next)
    // use your instace of i18next with vue
    const i18n = new VueI18Next(i18next)
    
    // init quasar 
    Quasar.start(() => {
      /* eslint-disable no-new */
      new Vue({
        el: '#q-app',
        i18n, // pass i18n: i18n
        .....
        // other arguments here as usual
      })
    })
    

    With this, you should be set up. try the following in any .vue component

    {{$t('key')}}
    

    If everything is working, this should render as ‘value’. Try adding a few more.

    Changing language

    First update your main.js i18next resources to look like so to look like so

    
        resources: {
          en: {
            translations: {
              hello: 'Hello World!' 
            }
          },
          es: {
            translations: {
              hello: 'Hola Mundo!' 
            }
          },
          fr: {
            translations: {
              hello: 'Bonjour Monde!' 
            }
          }
        }
    
    

    Now add {{$t('hello)}} in a .vue component.

    You should be able to change language with the following:

    
    changeLanguage (lng) {
      // where lng is one of 'es', 'fr', 'en'
      this.$i18n.i18next.changeLanguage(lng)
    }
    
    

    Accessing the current language

    This can be useful for choosing an icon representing the current language.

    
      this.$i18n.i18next.language 
    
    

    Using a xHR backend

    Having all your language data in main.js only works for the smallest of apps.
    Here is a way to pull language data from static .json files

    Add the following files

    /src/statics/i18n/en/translations.json

    {
      "hello": "Hello from backend"
    }
    

    /src/statics/i18n/es/translations.json

    {
      "hello": "Hola desde statics"
    }
    
    Install the XHR backend
      $  npm install --save i18next-xhr-backend
    

    src/main.js

    
    import i18next from 'i18next'
    import VueI18Next from '@panter/vue-i18next'
    import XHR from 'i18next-xhr-backend' // import xhr backend
    
    ....
    
    i18next
      .use(XHR) // Add  xhr backend to i18next 
      .init({
        debug: true,
        lng: 'en',
        ns: 'translations',
        backend: { // backend config
          loadPath: '/statics/i18n/{{lng}}/{{ns}}.json', // load path based on language and namespaces
          parse: data => JSON.parse(data) // parse data
        }
      }, (err, t) => {
        if (DEV && err) {
          console.log(err)
        }
      })
    
    

    This should set up the backend.

    Additional configuration options

    
    import i18next from 'i18next'
    import VueI18Next from '@panter/vue-i18next'
    import XHR from 'i18next-xhr-backend' // import xhr backend
    
    ....
    
    i18next
      .use(XHR)
      .init({
        debug: true,
        returnObjects: true, // this is very useful if you want translations to return an array on which you can use v-for
        lng: 'en',
        fallbackLng: 'en', // language to fallback to if current language is unavailable 
        ns: 'translations',
        defaultNS: 'translations',
        fallbackNS: 'translations' //  namespace to fallback to if current namespace is unavailable 
        backend: { // add backend
          loadPath: '/statics/i18n/{{lng}}/{{ns}}.json', // load path based on namespaces and language
          parse: data => JSON.parse(data) // parse data
        }
      }, (err, t) => {
        if (DEV && err) {
          console.log(err)
        }
      })
    
    

    And now in any .vue file, configure local namespaces for said file

    export default {
      .....
      i18nOptions: {
        namespaces: 'translations' // either string or array of strings. The corresponding files will be loaded
      }
      .....
    }
    
    Hope this helped

    I’m tired now. Will edit later. Please post if you spot any mistakes. Thanks you



  • I’ll try your method soon, and I will then plug my own i18next-firebase-backend instead, which I’ll opensource once all is well.
    Stay tuned


Log in to reply
 

Looks like your connection to Quasar Framework was lost, please wait while we try to reconnect.