From ae24a4476771d01ac489d6937dc2c73d0cbf30e7 Mon Sep 17 00:00:00 2001 From: Mrau Hu Date: Wed, 20 May 2020 18:19:52 +0300 Subject: [PATCH 1/3] Added `headers` to `context`. --- packages/vue-ssr/server/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vue-ssr/server/index.js b/packages/vue-ssr/server/index.js index de7e855..68f965a 100644 --- a/packages/vue-ssr/server/index.js +++ b/packages/vue-ssr/server/index.js @@ -91,7 +91,7 @@ onPageLoad(sink => new Promise((resolve, reject) => { // } // Vue - const context = { url: req.url } + const context = { url: req.url, headers } let asyncResult const result = VueSSR.createApp(context) if (result && typeof result.then === 'function') { From c7fdcecf886b73aa2e3829ff414d8a7d7bdaef76 Mon Sep 17 00:00:00 2001 From: Mrau Hu Date: Wed, 20 May 2020 18:24:09 +0300 Subject: [PATCH 2/3] Updated `README.md`: added example usage of request headers for the internationalization with meta tags. --- packages/vue-ssr/README.md | 137 +++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) diff --git a/packages/vue-ssr/README.md b/packages/vue-ssr/README.md index 7876772..337af1d 100644 --- a/packages/vue-ssr/README.md +++ b/packages/vue-ssr/README.md @@ -152,6 +152,143 @@ VueSSR.createApp = function (context) { } ``` +### Request headers for the internationalization with meta tags + +You can use `context.headers` for access to request headers from the server. + +Example usage with `vue-i18n` and `vue-meta` packages: + +`/imports/startup/server/vue-ssr.js` + +```js +VueSSR.createApp = function (context) { + return new Promise((resolve, reject) => { + const { app, router, store } = createApp({ + ssr: true, + headers: context.headers, + }) + }) +} +``` + +`/imports/startup/html-attr.js` + +```js +import { WebApp } from 'meteor/webapp'; +import { getHtmlLang } from '/imports/ui/i18n'; + +WebApp.addHtmlAttributeHook((req) => ({ + lang: getHtmlLang(req.headers), + // @see https://vue-meta.nuxtjs.org/faq/prevent-initial.html + 'data-vue-meta-server-rendered': '', +})); +``` + +`/imports/ui/i18n.js` + +```js +import Vue from 'vue'; +import VueI18n from 'vue-i18n'; + +const messages = { + en: { + hello: 'Hello', + }, + ru: { + hello: 'Здравствуйте', + } +}; + +Vue.use(VueI18n); + +const fallbackLocale = 'en' +const availableLocales = Object.keys(messages) + +function getLanguage({ ssr, headers }) { + return ( + !ssr + ? (typeof navigator.languages !== 'undefined' // Client-side + ? navigator.languages[0] + : navigator.language // Fallback for old browsers + ) : headers['accept-language'].split(',')[0] // Server-side + ).toLocaleLowerCase().substring(0, 2) +} + +export function createI18n({ ssr, headers }) { + return new VueI18n({ + locale: getLanguage({ ssr, headers }), + fallbackLocale, + messages, + }); +} + +export function getHtmlLang(headers) { + const locale = getLanguage({ + ssr: true, + headers, + }); + return availableLocales.includes(locale) + ? locale + : fallbackLocale +} +``` + +`/imports/ui/createApp.js` + +```js +function createApp(context) { + /* + https://ssr.vuejs.org/guide/structure.html#avoid-stateful-singletons + */ + const store = createStore() + const router = createRouter() + const i18n = createI18n(context) + + // sync the router with the vuex store. + // this registers `store.state.route` + sync(store, router); + + // Vuex state restoration + if (!context.ssr && window.__INITIAL_STATE__) { + // We initialize the store state with the data injected from the server + store.replaceState(window.__INITIAL_STATE__) + } + + const app = new Vue({ + el: '#app', + router, + store, + i18n, + ...App, + }) + + return { + app, + router, + store, + } +} +``` + +`/imports/ui/App.vue` + +```vue + + + +``` + --- LICENCE ISC - Created by Guillaume CHAU (@Akryum) From 7841777f0e6d244f26be3fa58593f3da4a3839c4 Mon Sep 17 00:00:00 2001 From: Mrau Hu Date: Thu, 21 May 2020 08:54:53 +0300 Subject: [PATCH 3/3] Updated `README.md`: added check for `accept-headers` in `getLanguage()` function. Fix: request without headers can crash application. --- packages/vue-ssr/README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/vue-ssr/README.md b/packages/vue-ssr/README.md index 337af1d..c5ba665 100644 --- a/packages/vue-ssr/README.md +++ b/packages/vue-ssr/README.md @@ -210,8 +210,11 @@ function getLanguage({ ssr, headers }) { ? (typeof navigator.languages !== 'undefined' // Client-side ? navigator.languages[0] : navigator.language // Fallback for old browsers - ) : headers['accept-language'].split(',')[0] // Server-side - ).toLocaleLowerCase().substring(0, 2) + ) : (headers && typeof headers['accept-language'] === 'string' // Server-side + ? headers['accept-language'].split(',')[0] + : fallbackLocale + ) + ).toLocaleLowerCase().substring(0, 2); } export function createI18n({ ssr, headers }) {