Nuxt.js i18n localization doesn’t work in SPA mode



I developed project Nuxt.js in universal mode and localized with i18n work fine, but now I want to change to in spa mode but i18n doesn’t change the language. this is code. file : nuxt.config.js

import colors from "vuetify/es5/util/colors";

export default {
  mode: "spa",
  /*
   ** Headers of the page
   */
  head: {
    meta: [
      { charset: "utf-8" },
      { name: "viewport", content: "width=device-width, initial-scale=1" },
      {
        hid: "description",
        name: "description",
        content: process.env.npm_package_description || ""
      }
    ],
    link: [
      { rel: "icon", type: "image/x-icon", href: "/favicon.ico" },
      {
        rel: "stylesheet",
        href:
          "https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons"
      }
    ]
  },
  /*
   ** Customize the progress-bar color
   */
  loading: { color: "#fff" },
  /*
   ** Global CSS
   */
  css: ["~/assets/main.css"],

  router: {
    middleware: "i18n"
  },
  /*
   ** Plugins to load before mounting the App
   */
  plugins: [
    "~/plugins/mdi-font.js",
    "~/plugins/i18n.js",
    "~/plugins/axios.js",
    { src: "~/plugins/flag.js", ssr: false }
  ],
  /*
   ** Nuxt.js modules
   */
  modules: [
    "@nuxtjs/vuetify",
    // Doc: https://axios.nuxtjs.org/usage
    "@nuxtjs/axios"
  ],
  /*
   ** Axios module configuration
   ** See https://axios.nuxtjs.org/options
   */
  axios: {},
  /*
   ** vuetify module configuration
   ** https://github.com/nuxt-community/vuetify-module
   */
  vuetify: {
    theme: {
      primary: colors.blue.darken2,
      accent: colors.grey.darken3,
      secondary: colors.amber.darken3,
      info: colors.teal.lighten1,
      warning: colors.amber.base,
      error: colors.deepOrange.accent4,
      success: colors.green.accent3
    }
  },
  /*
   ** Build configuration
   */
  build: {
    /*
     ** You can extend webpack config here
     */
    extend(config, ctx) {}
  }
};

file : middleware/i18n.js

export default function ({ isHMR, app, store, route, params, req, error, redirect }) {
    if (isHMR) { // ignore if called from hot module replacement
        return;
    }

    if (req) {
        if (route.name) {
            let locale = null;

            // check if the locale cookie is set
            if (req.headers.cookie) {
                const cookies = req.headers.cookie.split('; ').map(stringCookie => stringCookie.split('='));
                const cookie = cookies.find(cookie => cookie[0] === 'locale');

                if (cookie) {
                    locale = cookie[1];
                }
            }

            // if the locale cookie is not set, fallback to accept-language header
            if (!locale) {
                locale = req.headers['accept-language'].split(',')[0].toLocaleLowerCase().substring(0, 2);
            }

            store.commit('SET_LANG', locale);
            app.i18n.locale = store.state.locale;
        }
    }
};

store/index.js

export const state = () => ({
    locales: [
        {
            code: 'en',
            name: 'EN',
            flag: 'us'
        },
        {
            code: 'fa',
            name: 'FA',
            flag: 'af'
        },
        {
            code: 'pa',
            name: 'PA',
            flag: 'af'
        }
    ],
    locale: 'en'
});

export const mutations = {
    SET_LANG(state, locale) {
        if (state.locales.find(el => el.code === locale)) {
            state.locale = locale
        }
    }
};

and licalize file are in locales/fa.json and en.json

Answer

export default function ({ isHMR, app, store, route, params, req, error, redirect })

So bold parameter req is not receive in SAP mode. For more information you can visit this link.

So you have to try another way using another parameter, Just for example you can see below code:

export default function ({
  isHMR, app, store, route, params, error, redirect
}) {
    const defaultLocale = app.i18n.fallbackLocale
  // If middleware is called from hot module replacement, ignore it
  if (isHMR) return
  // Get locale from params

                const locale = params.lang || defaultLocale
                if (store.state.locales.indexOf(locale) === -1) {
                  return error({
                    message: 'This page could not be found.',
                    statusCode: 404
                  })
                }

  // Set locale
  store.commit('SET_LANG', locale)
  app.i18n.locale = store.state.locale
  // If route is /<defaultLocale>/... -> redirect to /...

              if (locale === defaultLocale && route.fullPath.indexOf('/' + defaultLocale) ===
                0) {
                const toReplace = '^/' + defaultLocale
                const re = new RegExp(toReplace)
                return redirect(
                  route.fullPath.replace(re, '/')
                )
        } 
}


Source: stackoverflow