Search code examples
vue.jsaxiosnuxt.jsvue-i18nnuxt-i18n

Accessing app context from custom .js files for fetching locale messages


I am building Vue.js application using Nuxt.js in SSR mode. I have axios and vue-i18n plugins in my project.

nuxt.config.js :

export default {
  mode: 'universal',
  // some irrelevant configs
  modules: [
    '@nuxtjs/axios',
    'nuxt-i18n',
  ],
  i18n: {
    locales: [
      {
        code: 'en',
        name: 'English',
        file: 'en-EN.js'
      },
      {
        code: 'de',
        name: 'Deutsch',
        file: 'de-DE.js'
      }],
    defaultLocale: 'en',
    vueI18n: {
      fallbackLocale: 'en',
    },
    lazy: true,
    langDir: 'locales/',
    vuex: {
      moduleName: 'i18n',
      syncLocale: true,
      syncMessages: true,
      syncRouteParams: true
    },
  },
  /* Axios module configuration */
  axios: {}
}

As you see i18n is set to lazy loading. And messages are taken from locales/en-EN.js and locales/de-DE.js files. In the files I want to make a request to a backend-api which will serve me messages. locales/en-EN.js :

export default async function (context) {
  return await context.$axios.get('backend-api');
}

However when I load the page it says that $axios is undefined: Cannot read property 'get' of undefined. But as soon as I start switching between languages, application receives translations. So my guess is that server while attempting to access $axios from context fails, but on client (Browser) it succeeds. What is the correct way of accessing $axios module from Nuxt context?


Solution

  • So I guess the problem is that locale files are called during injection of plugins (i18n) so axios is not yet available in the app context.

    So I have found a workaround:

    First, I have imported plain axios (in addition to nuxt module)

    npm i axios -S
    

    Then in locale files i have imported its instance inside export function:

    // en-En.js
    export default async function (context) {
    
      // axios is derived directly from lib instead of context
      const axios = require('axios').default;
    
      let localeMessages = null
    
      await axios.get(
          'backend-api'
      ).then((result) => {
        localeMessages = result.data
      }).catch(() => {
        localeMessages = {}
      });
    
      return localeMessages
    }
    

    Still not sure whether this is a valid way to do it, but for now it works