From 98a5cd48200c5355a9c00d0f53cac5db72fa63d6 Mon Sep 17 00:00:00 2001 From: "Pablo H. Paladino" Date: Thu, 27 Jan 2022 11:15:39 -0300 Subject: [PATCH] support optimize --- packages/core/README.md | 1 + packages/core/src/helpers/services.js | 18 +++++++++++-- packages/core/src/server.jsx | 38 +++++++++++++++------------ 3 files changed, 38 insertions(+), 19 deletions(-) diff --git a/packages/core/README.md b/packages/core/README.md index 7f6b7fc53..9c3e80e38 100644 --- a/packages/core/README.md +++ b/packages/core/README.md @@ -872,6 +872,7 @@ export CANON_LANGUAGE_DEFAULT="es" |`CANON_BASE_URL`|If hosting assets or running the server from a different location that the project folder, this variable can be used to define the base URL for all static assets. A `` tag will be added to the start of the `` tag.|`undefined`| |`CANON_GOOGLE_ANALYTICS`|The unique Google Analytics ID for the project (ex. `"UA-########-#"`). This also supports comma-separated values, if it's desired for pageviews to be reported to multiple analytics properties.|`undefined`| |`CANON_FACEBOOK_PIXEL`|The unique Facebook Pixel ID for the project (ex. `"################"`).|`undefined`| +|`CANON_GOOGLE_OPTIMIZE`|The unique Google Optimize ID to run user tests. It loads the [synchronous version](https://support.google.com/optimize/answer/9692472]). Read more [here](https://optimize.google.com): (ex. `"OPT-#######"`).|`undefined`| |`CANON_GDPR`|When set to `true`, tracking services like Google Analytics and Faceboook Pixel will only be loaded after the user accepts the usage of cookies and tracking. A pop-up Drawer will be shown on the bottom of the screen containing text and buttons that are editable in the locales JSON file.|`false`| |`CANON_GDPR_WAIT`|By default, if a user has not chosen whether to accept or reject the GDPR message, we will assume consent and not ask on subsequent page visits. If this env var is set to `true`, tracking services will only execute after the user has explicitly accepted.|`false`| |`CANON_GOOGLE_TAG_MANAGER`|The unique Google Tag Manager ID for the project (ex. `"GTM-#######"`).|`undefined`| diff --git a/packages/core/src/helpers/services.js b/packages/core/src/helpers/services.js index ef5059683..fd16944d8 100644 --- a/packages/core/src/helpers/services.js +++ b/packages/core/src/helpers/services.js @@ -28,13 +28,17 @@ const serviceJavaScript = { })(window,document,'https://static.hotjar.com/c/hotjar-','.js?sv=');` }; +const serviceHeadTag = { + GOOGLE_OPTIMIZE: id => `` +} + const serviceHTML = { GOOGLE_TAG_MANAGER: id => `` }; -const servicesAvailable = Object.keys(serviceJavaScript).filter(s => process.env[`CANON_${s}`] !== undefined); +const servicesAvailable = Object.keys(serviceJavaScript).filter(s => [undefined, ''].indexOf(process.env[`CANON_${s}`]) === -1); const servicesScript = servicesAvailable .map(s => ` @@ -51,4 +55,14 @@ const servicesBody = servicesAvailable `).join("\n"); -export {servicesAvailable, servicesBody, servicesScript}; +// Services that needs a JS tags scripts +const servicesHeadTagsAvailable = Object.keys(serviceHeadTag).filter(s => [undefined, ''].indexOf(process.env[`CANON_${s}`]) === -1); + +const servicesHeadTags = servicesHeadTagsAvailable + .map(s => ` + + ${serviceHeadTag[s](process.env[`CANON_${s}`])} + + `).join("\n"); + +export {servicesAvailable, servicesBody, servicesScript, servicesHeadTags}; diff --git a/packages/core/src/server.jsx b/packages/core/src/server.jsx index cb88a8376..e5161ce4d 100644 --- a/packages/core/src/server.jsx +++ b/packages/core/src/server.jsx @@ -13,7 +13,7 @@ import {initialState as appInitialState} from "$app/store"; import preRenderMiddleware from "./middlewares/preRenderMiddleware"; import pretty from "pretty"; import maybeRedirect from "./helpers/maybeRedirect"; -import {servicesAvailable, servicesBody, servicesScript} from "./helpers/services"; +import {servicesAvailable, servicesBody, servicesScript, servicesHeadTags} from "./helpers/services"; import yn from "yn"; import CanonProvider from "./CanonProvider"; @@ -30,27 +30,27 @@ const BASE_URL = process.env.CANON_BASE_URL || "/"; const basename = BASE_URL.replace(/^[A-z]{4,5}\:\/{2}[A-z0-9\.\-]{1,}\:{0,}[0-9]{0,4}/g, ""); const baseTag = process.env.CANON_BASE_URL === undefined ? "" : ` - `; + `; /** Returns the default server logic for rendering a page. */ -export default function(defaultStore = appInitialState, headerConfig, reduxMiddleware = false) { +export default function (defaultStore = appInitialState, headerConfig, reduxMiddleware = false) { - return function(req, res) { + return function (req, res) { const locale = req.i18n.language, - resources = req.i18n.getResourceBundle(req.i18n.language); + resources = req.i18n.getResourceBundle(req.i18n.language); const windowLocation = { basename, host: req.headers.host, hostname: req.headers.host.split(":")[0], - href: `${ req.protocol }://${ req.headers.host }${ req.url }`, - origin: `${ req.protocol }://${ req.headers.host }`, + href: `${req.protocol}://${req.headers.host}${req.url}`, + origin: `${req.protocol}://${req.headers.host}`, pathname: req.url.split("?")[0], port: req.headers.host.includes(":") ? req.headers.host.split(":")[1] : "80", - protocol: `${ req.protocol }:`, + protocol: `${req.protocol}:`, query: req.query, search: req.url.includes("?") ? `?${req.url.split("?")[1]}` : "" }; @@ -120,8 +120,8 @@ export default function(defaultStore = appInitialState, headerConfig, reduxMiddl const helmetContext = {}; let componentHTML, - scriptTags = "", - styleTags = ""; + scriptTags = "", + styleTags = ""; if (production) { @@ -152,7 +152,7 @@ export default function(defaultStore = appInitialState, headerConfig, reduxMiddl .replace(/\n/g, "\n "); const cssOrder = ["normalize", "blueprint", "canon"]; - const cssRegex = RegExp(`(?:${ cssOrder.join("|") })`); + const cssRegex = RegExp(`(?:${cssOrder.join("|")})`); styleTags = extractor .getStyleTags() @@ -198,26 +198,30 @@ export default function(defaultStore = appInitialState, headerConfig, reduxMiddl const serialize = obj => `JSON.parse('${jsesc(JSON.stringify(obj))}')`; return res.status(status).send(` - + + ${baseTag} - ${ pretty(header.title.toString()).replace(/\n/g, "\n ") } - ${ pretty(header.meta.toString()).replace(/\n/g, "\n ") } + ${servicesHeadTags} + + ${pretty(header.title.toString()).replace(/\n/g, "\n ")} + + ${pretty(header.meta.toString()).replace(/\n/g, "\n ")} - ${ pretty(header.link.toString()).replace(/\n/g, "\n ") } + ${pretty(header.link.toString()).replace(/\n/g, "\n ")} ${styleTags} ${servicesBody} -
${ componentHTML }
+
${componentHTML}