diff --git a/package.json b/package.json index ad6623823..1f329750d 100755 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "cookie": "^0.3.1", "esm": "3.0.28", "fs": "^0.0.1-security", + "js-cookie": "^2.2.0", "vue-i18n": "^7.8.0", "vue-i18n-extensions": "^0.1.0" }, diff --git a/src/module.js b/src/module.js index e5d2f4cdb..dbacdca21 100644 --- a/src/module.js +++ b/src/module.js @@ -51,7 +51,8 @@ export default function (userOptions) { getForwarded, getHostname, getLocaleDomain, - syncVuex + syncVuex, + isSpa: this.options.mode === 'spa' } // Generate localized routes diff --git a/src/templates/middleware.js b/src/templates/middleware.js index 30cef895e..0c36b8390 100644 --- a/src/templates/middleware.js +++ b/src/templates/middleware.js @@ -1,4 +1,5 @@ import cookie from 'cookie' +import Cookies from 'js-cookie' import middleware from '../middleware' middleware['i18n'] = async ({ app, req, res, route, store, redirect, isHMR }) => { @@ -10,6 +11,7 @@ middleware['i18n'] = async ({ app, req, res, route, store, redirect, isHMR }) => const lazy = <%= options.lazy %> const vuex = <%= JSON.stringify(options.vuex) %> const differentDomains = <%= options.differentDomains %> + const isSpa = <%= options.isSpa %> // Helpers const LOCALE_CODE_KEY = '<%= options.LOCALE_CODE_KEY %>' @@ -30,36 +32,62 @@ middleware['i18n'] = async ({ app, req, res, route, store, redirect, isHMR }) => // Handle browser language detection const detectBrowserLanguage = <%= JSON.stringify(options.detectBrowserLanguage) %> - if (detectBrowserLanguage && req && typeof req.headers['accept-language'] !== 'undefined') { - const browserLocale = req.headers['accept-language'] ? - req.headers['accept-language'].split(',')[0].toLocaleLowerCase().substring(0, 2) : null - const { useCookie, cookieKey } = detectBrowserLanguage - - const redirectToBrowserLocale = () => { - const routeName = route && route.name ? app.getRouteBaseName(route) : 'index' - if (browserLocale && browserLocale !== app.i18n.locale && locales.indexOf(browserLocale) !== -1) { - redirect(app.localePath(Object.assign({}, route , { - name: routeName - }), browserLocale)) - } + + if (detectBrowserLanguage) { + // Get browser language either from navigator if running in mode SPA, or from the headers + let browserLocale = null + if (isSpa && typeof navigator !== 'undefined' && navigator.language) { + browserLocale = navigator.language.toLocaleLowerCase().substring(0, 2) + } else if (req && typeof req.headers['accept-language'] !== 'undefined') { + browserLocale = req.headers['accept-language'].split(',')[0].toLocaleLowerCase().substring(0, 2) } - // Handle cookie option to prevent multiple redirections - if (useCookie) { - const cookies = req.headers && req.headers.cookie ? cookie.parse(req.headers.cookie) : {} - if (!cookies[cookieKey]) { - // Set cookie - if (useCookie && res) { - const date = new Date() + if (browserLocale) { + const { useCookie, cookieKey } = detectBrowserLanguage + + const redirectToBrowserLocale = () => { + const routeName = route && route.name ? app.getRouteBaseName(route) : 'index' + if (browserLocale && browserLocale !== app.i18n.locale && locales.indexOf(browserLocale) !== -1) { + redirect(app.localePath(Object.assign({}, route , { + name: routeName + }), browserLocale)) + } + } + + const getCookie = () => { + if (isSpa) { + return Cookies.get(cookieKey); + } else if (req && typeof req.headers.cookie !== 'undefined') { + const cookies = req.headers && req.headers.cookie ? cookie.parse(req.headers.cookie) : {} + return cookies[cookieKey] + } + return null + } + + const setCookie = () => { + const date = new Date() + if (isSpa) { + Cookies.set(cookieKey, 1, { + expires: new Date(date.setDate(date.getDate() + 365)) + }) + } else if (res) { const redirectCookie = cookie.serialize(cookieKey, 1, { expires: new Date(date.setDate(date.getDate() + 365)) }) res.setHeader('Set-Cookie', redirectCookie) } + } + + // Handle cookie option to prevent multiple redirections + if (useCookie) { + if (!getCookie()) { + // Set cookie + setCookie() + redirectToBrowserLocale() + } + } else { redirectToBrowserLocale() } - } else { - redirectToBrowserLocale() } } diff --git a/yarn.lock b/yarn.lock index a189c4346..1167b7a94 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5498,6 +5498,10 @@ js-base64@^2.1.9: version "2.4.3" resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.4.3.tgz#2e545ec2b0f2957f41356510205214e98fad6582" +js-cookie@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-2.2.0.tgz#1b2c279a6eece380a12168b92485265b35b1effb" + js-tokens@^3.0.0, js-tokens@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"