From cee3e6e29c058c44c5198e3a993ad8bd3299d832 Mon Sep 17 00:00:00 2001 From: Dhenain Ambroise Date: Sun, 26 Apr 2020 15:25:22 +0200 Subject: [PATCH 001/459] Display APP_VERSION and APP_VERSION_RELEASE in /api/status --- src/pages/api/status.ts | 2 ++ src/utils/sentry.ts | 1 + 2 files changed, 3 insertions(+) diff --git a/src/pages/api/status.ts b/src/pages/api/status.ts index 10ee191dc..0b188a702 100644 --- a/src/pages/api/status.ts +++ b/src/pages/api/status.ts @@ -13,6 +13,8 @@ export const status = async (req: NowRequest, res: NowResponse): Promise = configureReq(req); res.json({ + version: process.env.APP_VERSION, + release: process.env.APP_VERSION_RELEASE, nodejs: process.version, nodejsAWS: process.env.AWS_EXECUTION_ENV, regionNOW: process.env.NOW_REGION, diff --git a/src/utils/sentry.ts b/src/utils/sentry.ts index 949922519..343ff9272 100644 --- a/src/utils/sentry.ts +++ b/src/utils/sentry.ts @@ -23,6 +23,7 @@ if (!process.env.SENTRY_DSN && process.env.NODE_ENV !== 'test') { // Scope configured by default, subsequent calls to "configureScope" will add additional data Sentry.configureScope((scope) => { // See https://www.npmjs.com/package/@sentry/node + scope.setTag('appVersion', process.env.APP_VERSION); scope.setTag('nodejs', process.version); scope.setTag('nodejsAWS', process.env.AWS_EXECUTION_ENV || null); // Optional - Available on production environment only scope.setTag('memory', process.env.AWS_LAMBDA_FUNCTION_MEMORY_SIZE || null); // Optional - Available on production environment only From 58bca458ed79e80ba920fa89ca27ea6f089e93de Mon Sep 17 00:00:00 2001 From: Dhenain Ambroise Date: Sun, 26 Apr 2020 15:41:08 +0200 Subject: [PATCH 002/459] Rename preset used in this branch from "v1-ssr-mst-aptd-gcms-lcz-sty" to "v1-hyb-mst-aptd-gcms-lcz-sty" --- .env.build.example | 2 +- cypress/config-customer1.json | 2 +- cypress/config-customer2.json | 2 +- now.customer1.production.json | 4 ++-- now.customer1.staging.json | 4 ++-- now.customer2.production.json | 4 ++-- now.customer2.staging.json | 4 ++-- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.env.build.example b/.env.build.example index cae7cc9e9..8669d1f31 100644 --- a/.env.build.example +++ b/.env.build.example @@ -9,7 +9,7 @@ NODE_ENV=development APP_STAGE=development # The NRN preset used for the demo -NRN_PRESET=v1-ssr-mst-aptd-gcms-lcz-sty +NRN_PRESET=v1-hyb-mst-aptd-gcms-lcz-sty # The customer that is being deployed CUSTOMER_REF=customer1 diff --git a/cypress/config-customer1.json b/cypress/config-customer1.json index 76a1e8ac6..6d260d39d 100644 --- a/cypress/config-customer1.json +++ b/cypress/config-customer1.json @@ -1,5 +1,5 @@ { - "baseUrl": "https://nrn-v1-ssr-mst-aptd-gcms-lcz-sty-c1.now.sh/", + "baseUrl": "https://nrn-v1-hyb-mst-aptd-gcms-lcz-sty-c1.now.sh/", "projectId": "4dvdog", "screenshotsFolder": "cypress/screenshots/customer1", "videosFolder": "cypress/videos/customer1", diff --git a/cypress/config-customer2.json b/cypress/config-customer2.json index 069f85bb9..804b80d31 100644 --- a/cypress/config-customer2.json +++ b/cypress/config-customer2.json @@ -1,5 +1,5 @@ { - "baseUrl": "https://nrn-v1-ssr-mst-aptd-gcms-lcz-sty-c2.now.sh/", + "baseUrl": "https://nrn-v1-hyb-mst-aptd-gcms-lcz-sty-c2.now.sh/", "projectId": "4dvdog", "screenshotsFolder": "cypress/screenshots/customer2", "videosFolder": "cypress/videos/customer2", diff --git a/now.customer1.production.json b/now.customer1.production.json index cfe62438f..18a056a3c 100644 --- a/now.customer1.production.json +++ b/now.customer1.production.json @@ -1,12 +1,12 @@ { "version": 2, - "name": "nrn-v1-ssr-mst-aptd-gcms-lcz-sty-c1", + "name": "nrn-v1-hyb-mst-aptd-gcms-lcz-sty-c1", "scope": "team_qnVfSEVc2WwmOE1OYhZr4VST", "env": {}, "build": { "env": { "APP_STAGE": "production", - "NRN_PRESET": "v1-ssr-mst-aptd-gcms-lcz-sty", + "NRN_PRESET": "v1-hyb-mst-aptd-gcms-lcz-sty", "CUSTOMER_REF": "customer1", "GRAPHQL_API_ENDPOINT": "https://api-euwest.graphcms.com/v1/ck73ixhlv09yt01dv2ga1bkbp/master", "GRAPHQL_API_KEY": "@nrn-graphql-api-key", diff --git a/now.customer1.staging.json b/now.customer1.staging.json index 6aafacc70..36ca7fe5f 100644 --- a/now.customer1.staging.json +++ b/now.customer1.staging.json @@ -1,12 +1,12 @@ { "version": 2, - "name": "nrn-v1-ssr-mst-aptd-gcms-lcz-sty-c1", + "name": "nrn-v1-hyb-mst-aptd-gcms-lcz-sty-c1", "scope": "team_qnVfSEVc2WwmOE1OYhZr4VST", "env": {}, "build": { "env": { "APP_STAGE": "staging", - "NRN_PRESET": "v1-ssr-mst-aptd-gcms-lcz-sty", + "NRN_PRESET": "v1-hyb-mst-aptd-gcms-lcz-sty", "CUSTOMER_REF": "customer1", "GRAPHQL_API_ENDPOINT": "https://api-euwest.graphcms.com/v1/ck73ixhlv09yt01dv2ga1bkbp/master", "GRAPHQL_API_KEY": "@nrn-graphql-api-key", diff --git a/now.customer2.production.json b/now.customer2.production.json index bbb2a3b44..a38e1834f 100644 --- a/now.customer2.production.json +++ b/now.customer2.production.json @@ -1,12 +1,12 @@ { "version": 2, - "name": "nrn-v1-ssr-mst-aptd-gcms-lcz-sty-c2", + "name": "nrn-v1-hyb-mst-aptd-gcms-lcz-sty-c2", "scope": "team_qnVfSEVc2WwmOE1OYhZr4VST", "env": {}, "build": { "env": { "APP_STAGE": "production", - "NRN_PRESET": "v1-ssr-mst-aptd-gcms-lcz-sty", + "NRN_PRESET": "v1-hyb-mst-aptd-gcms-lcz-sty", "CUSTOMER_REF": "customer2", "GRAPHQL_API_ENDPOINT": "https://api-euwest.graphcms.com/v1/ck73ixhlv09yt01dv2ga1bkbp/master", "GRAPHQL_API_KEY": "@nrn-graphql-api-key", diff --git a/now.customer2.staging.json b/now.customer2.staging.json index d5940d475..78faf109d 100644 --- a/now.customer2.staging.json +++ b/now.customer2.staging.json @@ -1,12 +1,12 @@ { "version": 2, - "name": "nrn-v1-ssr-mst-aptd-gcms-lcz-sty-c2", + "name": "nrn-v1-hyb-mst-aptd-gcms-lcz-sty-c2", "scope": "team_qnVfSEVc2WwmOE1OYhZr4VST", "env": {}, "build": { "env": { "APP_STAGE": "staging", - "NRN_PRESET": "v1-ssr-mst-aptd-gcms-lcz-sty", + "NRN_PRESET": "v1-hyb-mst-aptd-gcms-lcz-sty", "CUSTOMER_REF": "customer2", "GRAPHQL_API_ENDPOINT": "https://api-euwest.graphcms.com/v1/ck73ixhlv09yt01dv2ga1bkbp/master", "GRAPHQL_API_KEY": "@nrn-graphql-api-key", From 84569a517348844e023aada20933398cdbadc161 Mon Sep 17 00:00:00 2001 From: Dhenain Ambroise Date: Sun, 26 Apr 2020 18:16:56 +0200 Subject: [PATCH 003/459] Add missing Next.js TS types --- src/types/GetServerSidePropsContext.ts | 17 +++++++++++++++++ src/types/GetStaticPropsContext.ts | 13 +++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 src/types/GetServerSidePropsContext.ts create mode 100644 src/types/GetStaticPropsContext.ts diff --git a/src/types/GetServerSidePropsContext.ts b/src/types/GetServerSidePropsContext.ts new file mode 100644 index 000000000..5215f2e09 --- /dev/null +++ b/src/types/GetServerSidePropsContext.ts @@ -0,0 +1,17 @@ +import { IncomingMessage, ServerResponse } from 'http'; +import { ParsedUrlQuery } from 'querystring'; + +/** + * Context type used by "getServerSideProps" + * + * @see https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering + * @see node_modules/next/types/index.d.ts + */ +export declare type GetServerSidePropsContext = { + req: IncomingMessage; + res: ServerResponse; + params?: Q; + query: ParsedUrlQuery; + preview?: boolean; + previewData?: any; +}; diff --git a/src/types/GetStaticPropsContext.ts b/src/types/GetStaticPropsContext.ts new file mode 100644 index 000000000..d2730de52 --- /dev/null +++ b/src/types/GetStaticPropsContext.ts @@ -0,0 +1,13 @@ +import { ParsedUrlQuery } from 'querystring'; + +/** + * Context type used by "getStaticProps" + * + * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation + * @see node_modules/next/types/index.d.ts + */ +export declare type GetStaticPropsContext = { + params?: Q + preview?: boolean + previewData?: any +}; From f747475d158a0d12b014d9bf1a386259722d7598 Mon Sep 17 00:00:00 2001 From: Dhenain Ambroise Date: Sun, 26 Apr 2020 19:14:21 +0200 Subject: [PATCH 004/459] POC - Implement basic getStaticProps for "index" page (use SSG instead of SSR) --- src/pages/index.tsx | 65 +++++++++++++++++++++++++++++++++++++-- src/types/AppPageProps.ts | 6 ++-- 2 files changed, 65 insertions(+), 6 deletions(-) diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 816d776a9..b65225b8e 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -2,22 +2,29 @@ import { Amplitude, LogOnMount } from '@amplitude/react-amplitude'; import { css, jsx } from '@emotion/core'; import * as Sentry from '@sentry/node'; +import { universalLanguageDetect } from '@unly/universal-language-detector'; +import { ERROR_LEVELS } from '@unly/universal-language-detector/lib/utils/error'; import { isBrowser } from '@unly/utils'; import { createLogger } from '@unly/utils-simple-logger'; -import { NextPage } from 'next'; +import { GetStaticProps, NextPage } from 'next'; import Link from 'next/link'; // eslint-disable-next-line @typescript-eslint/no-unused-vars,no-unused-vars import React from 'react'; import { Alert, Container } from 'reactstrap'; import Head from '../components/Head'; +import { AppPageProps } from '../types/AppPageProps'; +import { GetStaticPropsContext } from '../types/GetStaticPropsContext'; import { PageProps } from '../types/PageProps'; +import { prepareGraphCMSLocaleHeader } from '../utils/graphcms'; +import { LANG_EN, resolveFallbackLanguage, SUPPORTED_LANGUAGES } from '../utils/i18n'; +import { fetchTranslations, I18nextResources } from '../utils/i18nextLocize'; const fileLabel = 'pages/index'; const logger = createLogger({ // eslint-disable-line no-unused-vars,@typescript-eslint/no-unused-vars label: fileLabel, }); -const Home: NextPage = (props: PageProps): JSX.Element => { +const Home: NextPage = (props: AppPageProps): JSX.Element => { Sentry.addBreadcrumb({ // See https://docs.sentry.io/enriching-error-data/breadcrumbs category: fileLabel, message: `Rendering index page (${isBrowser() ? 'browser' : 'server'})`, @@ -94,7 +101,14 @@ const Home: NextPage = (props: PageProps): JSX.Element => {

Overview

- You can navigate between /examples and / to see CSR in action.
+ You can navigate between /examples and  + + {/* eslint-disable-next-line jsx-a11y/anchor-is-valid */} + / + to see CSR in action.
You can also disable JS on your browser to see how SSR works.

If you want to know a bit more about what's running this demo beneath the surface, check out our /api/status endpoint! @@ -193,7 +207,52 @@ const Home: NextPage = (props: PageProps): JSX.Element => { )} ); +}; + +/** + * Only executed on the server side at build time. + * + * When a page uses "getStaticProps", then "_app:getInitialProps" is executed but not actually used by the page, + * only the results from getStaticProps are used. + * + * @param context + * @return Props that will be passed to the Page component, as props + * + * @see https://github.com/zeit/next.js/discussions/10949#discussioncomment-6884 + * @see https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation + */ +export const getStaticProps: GetStaticProps = async (context: GetStaticPropsContext): Promise<{ props: AppPageProps }> => { + console.log('getStaticProps', context); + + const lang: string = universalLanguageDetect({ + supportedLanguages: SUPPORTED_LANGUAGES, // Whitelist of supported languages, will be used to filter out languages that aren't supported + fallbackLanguage: LANG_EN, // Fallback language in case the user's language cannot be resolved + acceptLanguageHeader: null, + serverCookies: null, + errorHandler: (error: Error, level: ERROR_LEVELS, origin: string, context: object): void => { + Sentry.withScope((scope): void => { + scope.setExtra('level', level); + scope.setExtra('origin', origin); + scope.setContext('context', context); + Sentry.captureException(error); + }); + logger.error(error.message); + }, + }); + const bestCountryCodes: string[] = [lang, resolveFallbackLanguage(lang)]; + const gcmsLocales: string = prepareGraphCMSLocaleHeader(bestCountryCodes); + const defaultLocales: I18nextResources = await fetchTranslations(lang); // Pre-fetches translations from Locize API + return { + props: { + customerRef: process.env.CUSTOMER_REF, + isSSRReadyToRender: true, + lang, + bestCountryCodes, + gcmsLocales, + defaultLocales, + }, + }; }; export default Home; diff --git a/src/types/AppPageProps.ts b/src/types/AppPageProps.ts index 328e75282..174d4e210 100644 --- a/src/types/AppPageProps.ts +++ b/src/types/AppPageProps.ts @@ -13,9 +13,9 @@ import { UserSemiPersistentSession } from './UserSemiPersistentSession'; */ export declare type AppPageProps = { customerRef: string; - headers: PublicHeaders; // Headers made public to the client-side - readonlyCookies: Cookies; // Cookies retrieved using https://www.npmjs.com/package/next-cookies - Aren't really readonly but don't provide any setter - userSession: UserSemiPersistentSession; + headers?: PublicHeaders; // SSR only - Headers made public to the client-side + readonlyCookies?: Cookies; // SSR only - Cookies retrieved using https://www.npmjs.com/package/next-cookies - Aren't really readonly but don't provide any setter + userSession?: UserSemiPersistentSession; // SSR only - User session (cookies) bestCountryCodes: string[]; gcmsLocales: string; lang: string; From abefe61b12a59c33b975f38d3554634ac75f726a Mon Sep 17 00:00:00 2001 From: Dhenain Ambroise Date: Sun, 26 Apr 2020 20:07:46 +0200 Subject: [PATCH 005/459] Add try/catch block to avoid crash on cookie read (SSG failure at build step for unknown reason) --- src/utils/UniversalCookiesManager.ts | 36 +++++++++++++++------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/utils/UniversalCookiesManager.ts b/src/utils/UniversalCookiesManager.ts index 1144c2a4f..182fc72c6 100644 --- a/src/utils/UniversalCookiesManager.ts +++ b/src/utils/UniversalCookiesManager.ts @@ -54,24 +54,28 @@ export default class UniversalCookiesManager { * @param browserOptions */ replaceUserData(newUserData: UserSemiPersistentSession, serverOptions = this.defaultServerOptions, browserOptions: CookieAttributes = this.defaultBrowserOptions): void { - if (isBrowser()) { - // XXX By default, "js-cookies" apply a "percent encoding" when writing data, which isn't compatible with the "cookies" lib - // We therefore override this behaviour because we need to write proper JSON - // See https://github.com/js-cookie/js-cookie#encoding - const browserCookies = BrowserCookies.withConverter({ - write: function (value: string, name: string) { - return value; - }, - }); - browserCookies.set(USER_LS_KEY, JSON.stringify(newUserData), browserOptions); - } else { - const serverCookies = new ServerCookies(this.req, this.res); + try { + if (isBrowser()) { + // XXX By default, "js-cookies" apply a "percent encoding" when writing data, which isn't compatible with the "cookies" lib + // We therefore override this behaviour because we need to write proper JSON + // See https://github.com/js-cookie/js-cookie#encoding + const browserCookies = BrowserCookies.withConverter({ + write: function (value: string, name: string) { + return value; + }, + }); + browserCookies.set(USER_LS_KEY, JSON.stringify(newUserData), browserOptions); + } else { + const serverCookies = new ServerCookies(this.req, this.res); - // If running on the server side but req or res aren't set, then we don't do anything - // It's likely because we're calling this code from a view (that doesn't belong to getInitialProps and doesn't have access to req/res even though if it's running on the server) - if (this.req && this.res) { - serverCookies.set(USER_LS_KEY, JSON.stringify(newUserData), serverOptions); + // If running on the server side but req or res aren't set, then we don't do anything + // It's likely because we're calling this code from a view (that doesn't belong to getInitialProps and doesn't have access to req/res even though if it's running on the server) + if (this.req && this.res) { + serverCookies.set(USER_LS_KEY, JSON.stringify(newUserData), serverOptions); + } } + } catch (e) { + Sentry.captureException(e); } } From f309835528ce51f009470a5fec5ed2ef69f25243 Mon Sep 17 00:00:00 2001 From: Dhenain Ambroise Date: Sun, 26 Apr 2020 20:21:06 +0200 Subject: [PATCH 006/459] Random attempt trying to fix zeit aliasing --- .github/workflows/deploy-zeit-staging.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy-zeit-staging.yml b/.github/workflows/deploy-zeit-staging.yml index 2cecbe90b..64bf43749 100644 --- a/.github/workflows/deploy-zeit-staging.yml +++ b/.github/workflows/deploy-zeit-staging.yml @@ -51,8 +51,8 @@ jobs: # Also, in order to remove forbidden characters, we create a sequence from ascii numbers using ranges of numbers (we forbid characters by using `seq X Y` and we add others by using ';'). # All special characters are converted to `-` (using `tr $0 $1` where $0 is replaced by $1), and only 0-9 and a-Z chars are kept intact. # We then use `awk` to convert "ascii numbers" back into actual characters. - # You can find the numbers equivalence by tapping `man ascii` and look at the "decimal" set. - ZEIT_DEPLOYMENT_ALIAS=$(echo $ZEIT_DEPLOYMENT_ALIAS | head -c 46 | tr "`(seq 0 47 ; seq 58 64 ; seq 91 96 && seq 123 127) | awk '{printf("%c",$1)}'`" -).now.sh + # You can find the numbers equivalence by tapping `man ascii` and look at the "decimal" set. + ZEIT_DEPLOYMENT_ALIAS=$(echo $ZEIT_DEPLOYMENT_ALIAS | head -c 45 | tr "`(seq 0 47 ; seq 58 64 ; seq 91 96 && seq 123 127) | awk '{printf("%c",$1)}'`" -).now.sh echo "::set-env name=ZEIT_DEPLOYMENT_ALIAS::https://$ZEIT_DEPLOYMENT_ALIAS" npx now alias $ZEIT_DEPLOYMENT_URL https://$ZEIT_DEPLOYMENT_ALIAS --token $ZEIT_TOKEN From 891a590b08e064a020ab0111938726c19d8e19c5 Mon Sep 17 00:00:00 2001 From: Dhenain Ambroise Date: Sun, 26 Apr 2020 20:27:06 +0200 Subject: [PATCH 007/459] Revert - Random attempt trying to fix zeit aliasing --- .github/workflows/deploy-zeit-staging.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/deploy-zeit-staging.yml b/.github/workflows/deploy-zeit-staging.yml index 64bf43749..9b0a44de8 100644 --- a/.github/workflows/deploy-zeit-staging.yml +++ b/.github/workflows/deploy-zeit-staging.yml @@ -46,13 +46,13 @@ jobs: else ZEIT_DEPLOYMENT_ALIAS=$(cat now.json | jq -r '.name')-${CURRENT_BRANCH##*/} fi - + # Zeit alias only allows 53 characters in the domain name, so we only keep the first 46 characters (because Zeit needs 7 chars for ".now.sh" at the end of the domain name) - # Also, in order to remove forbidden characters, we create a sequence from ascii numbers using ranges of numbers (we forbid characters by using `seq X Y` and we add others by using ';'). - # All special characters are converted to `-` (using `tr $0 $1` where $0 is replaced by $1), and only 0-9 and a-Z chars are kept intact. + # Also, in order to remove forbidden characters, we create a sequence from ascii numbers using ranges of numbers (we forbid characters by using `seq X Y` and we add others by using ';'). + # All special characters are converted to `-` (using `tr $0 $1` where $0 is replaced by $1), and only 0-9 and a-Z chars are kept intact. # We then use `awk` to convert "ascii numbers" back into actual characters. # You can find the numbers equivalence by tapping `man ascii` and look at the "decimal" set. - ZEIT_DEPLOYMENT_ALIAS=$(echo $ZEIT_DEPLOYMENT_ALIAS | head -c 45 | tr "`(seq 0 47 ; seq 58 64 ; seq 91 96 && seq 123 127) | awk '{printf("%c",$1)}'`" -).now.sh + ZEIT_DEPLOYMENT_ALIAS=$(echo $ZEIT_DEPLOYMENT_ALIAS | head -c 46 | tr "`(seq 0 47 ; seq 58 64 ; seq 91 96 && seq 123 127) | awk '{printf("%c",$1)}'`" -).now.sh echo "::set-env name=ZEIT_DEPLOYMENT_ALIAS::https://$ZEIT_DEPLOYMENT_ALIAS" npx now alias $ZEIT_DEPLOYMENT_URL https://$ZEIT_DEPLOYMENT_ALIAS --token $ZEIT_TOKEN From f9259c29d7ea5f9fa231bd959dda0e719d148b94 Mon Sep 17 00:00:00 2001 From: Dhenain Ambroise Date: Tue, 28 Apr 2020 10:20:57 +0200 Subject: [PATCH 008/459] Add fix for FB as browser --- .../detect-outdated-browser/outdated-browser-rework.min.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/public/static/CDN/detect-outdated-browser/outdated-browser-rework.min.js b/public/static/CDN/detect-outdated-browser/outdated-browser-rework.min.js index c4b7db4e7..b82bbbb79 100644 --- a/public/static/CDN/detect-outdated-browser/outdated-browser-rework.min.js +++ b/public/static/CDN/detect-outdated-browser/outdated-browser-rework.min.js @@ -1,4 +1,6 @@ !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).outdatedBrowserRework=e()}}(function(){return function u(r,s,l){function n(i,e){if(!s[i]){if(!r[i]){var o="function"==typeof require&&require;if(!e&&o)return o(i,!0);if(d)return d(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var t=s[i]={exports:{}};r[i][0].call(t.exports,function(e){var o=r[i][1][e];return n(o||e)},t,t.exports,u,r,s,l)}return s[i].exports}for(var d="function"==typeof require&&require,e=0;e"+f.update.web+''+f.callToAction+"

",googlePlay:"

"+f.update.googlePlay+''+f.callToAction+"

",appStore:"

"+f.update[u]+"

"}[u],v=f.outOfDate,k()&&f.unsupported&&(v=f.unsupported),'
'+v+"
"+h+'

×

'),c=document.getElementById("buttonCloseUpdateBrowser"),w=document.getElementById("buttonUpdateBrowser"),i.style.backgroundColor=t,i.style.color=r,i.children[0].children[0].style.color=r,i.children[0].children[1].style.color=r,w&&(w.style.color=r,w.style.borderColor&&(w.style.borderColor=r),w.onmouseover=function(){this.style.color=t,this.style.backgroundColor=r},w.onmouseout=function(){this.style.color=r,this.style.backgroundColor=t}),c.style.color=r,c.onmousedown=function(){return!(i.style.display="none")}}},o=window.onload;"function"!=typeof window.onload?window.onload=e:window.onload=function(){o&&o(),e()}}},{"./extend":1,"./languages.json":3,"ua-parser-js":4}],3:[function(e,o,i){o.exports={br:{outOfDate:"O seu navegador está desatualizado!",update:{web:"Atualize o seu navegador para ter uma melhor experiência e visualização deste site. ",googlePlay:"Please install Chrome from Google Play",appStore:"Please update iOS from the Settings App"},url:"https://browser-update.org/update-browser.html#br",callToAction:"Atualize o seu navegador agora",close:"Fechar"},ca:{outOfDate:"El vostre navegador no està actualitzat!",update:{web:"Actualitzeu el vostre navegador per veure correctament aquest lloc web. ",googlePlay:"Instal·leu Chrome des de Google Play",appStore:"Actualitzeu iOS des de l'aplicació Configuració"},url:"https://browser-update.org/update-browser.html#es",callToAction:"Actualitzar el meu navegador ara",close:"Tancar"},cn:{outOfDate:"您的浏览器已过时",update:{web:"要正常浏览本网站请升级您的浏览器。",googlePlay:"Please install Chrome from Google Play",appStore:"Please update iOS from the Settings App"},url:"https://browser-update.org/update-browser.html#cn",callToAction:"现在升级",close:"关闭"},cz:{outOfDate:"Váš prohlížeč je zastaralý!",update:{web:"Pro správné zobrazení těchto stránek aktualizujte svůj prohlížeč. ",googlePlay:"Nainstalujte si Chrome z Google Play",appStore:"Aktualizujte si systém iOS"},url:"https://browser-update.org/update-browser.html#cz",callToAction:"Aktualizovat nyní svůj prohlížeč",close:"Zavřít"},da:{outOfDate:"Din browser er forældet!",update:{web:"Opdatér din browser for at få vist denne hjemmeside korrekt. ",googlePlay:"Installér venligst Chrome fra Google Play",appStore:"Opdatér venligst iOS"},url:"https://browser-update.org/update-browser.html#da",callToAction:"Opdatér din browser nu",close:"Luk"},de:{outOfDate:"Ihr Browser ist veraltet!",update:{web:"Bitte aktualisieren Sie Ihren Browser, um diese Website korrekt darzustellen. ",googlePlay:"Please install Chrome from Google Play",appStore:"Please update iOS from the Settings App"},url:"https://browser-update.org/update-browser.html#de",callToAction:"Den Browser jetzt aktualisieren ",close:"Schließen"},ee:{outOfDate:"Sinu veebilehitseja on vananenud!",update:{web:"Palun uuenda oma veebilehitsejat, et näha lehekülge korrektselt. ",googlePlay:"Please install Chrome from Google Play",appStore:"Please update iOS from the Settings App"},url:"https://browser-update.org/update-browser.html#ee",callToAction:"Uuenda oma veebilehitsejat kohe",close:"Sulge"},en:{outOfDate:"Your browser is out-of-date!",update:{web:"Update your browser to view this website correctly. ",googlePlay:"Please install Chrome from Google Play",appStore:"Please update iOS from the Settings App"},url:"https://browser-update.org/update-browser.html#",callToAction:"Update my browser now",close:"Close"},es:{outOfDate:"¡Tu navegador está anticuado!",update:{web:"Actualiza tu navegador para ver esta página correctamente. ",googlePlay:"Please install Chrome from Google Play",appStore:"Please update iOS from the Settings App"},url:"https://browser-update.org/update-browser.html#es",callToAction:"Actualizar mi navegador ahora",close:"Cerrar"},fa:{rightToLeft:!0,outOfDate:"مرورگر شما منسوخ شده است!",update:{web:"جهت مشاهده صحیح این وبسایت، مرورگرتان را بروز رسانی نمایید. ",googlePlay:"Please install Chrome from Google Play",appStore:"Please update iOS from the Settings App"},url:"https://browser-update.org/update-browser.html#",callToAction:"همین حالا مرورگرم را بروز کن",close:"Close"},fi:{outOfDate:"Selaimesi on vanhentunut!",update:{web:"Lataa ajantasainen selain nähdäksesi tämän sivun oikein. ",googlePlay:"Asenna uusin Chrome Google Play -kaupasta",appStore:"Päivitä iOS puhelimesi asetuksista"},url:"https://browser-update.org/update-browser.html#fi",callToAction:"Päivitä selaimeni nyt ",close:"Sulje"},fr:{outOfDate:"Votre navigateur n'est plus compatible !",update:{web:"Mettez à jour votre navigateur pour afficher correctement ce site Web. ",googlePlay:"Merci d'installer Chrome depuis le Google Play Store",appStore:"Merci de mettre à jour iOS depuis l'application Réglages"},url:"https://browser-update.org/update-browser.html#fr",callToAction:"Mettre à jour maintenant ",close:"Fermer"},hu:{outOfDate:"A böngészője elavult!",update:{web:"Firssítse vagy cserélje le a böngészőjét. ",googlePlay:"Please install Chrome from Google Play",appStore:"Please update iOS from the Settings App"},url:"https://browser-update.org/update-browser.html#hu",callToAction:"A böngészőm frissítése ",close:"Close"},id:{outOfDate:"Browser yang Anda gunakan sudah ketinggalan zaman!",update:{web:"Perbaharuilah browser Anda agar bisa menjelajahi website ini dengan nyaman. ",googlePlay:"Please install Chrome from Google Play",appStore:"Please update iOS from the Settings App"},url:"https://browser-update.org/update-browser.html#",callToAction:"Perbaharui browser sekarang ",close:"Close"},it:{outOfDate:"Il tuo browser non è aggiornato!",update:{web:"Aggiornalo per vedere questo sito correttamente. ",googlePlay:"Please install Chrome from Google Play",appStore:"Please update iOS from the Settings App"},url:"https://browser-update.org/update-browser.html#it",callToAction:"Aggiorna ora",close:"Chiudi"},lt:{outOfDate:"Jūsų naršyklės versija yra pasenusi!",update:{web:"Atnaujinkite savo naršyklę, kad galėtumėte peržiūrėti šią svetainę tinkamai. ",googlePlay:"Please install Chrome from Google Play",appStore:"Please update iOS from the Settings App"},url:"https://browser-update.org/update-browser.html#",callToAction:"Atnaujinti naršyklę ",close:"Close"},nl:{outOfDate:"Je gebruikt een oude browser!",update:{web:"Update je browser om deze website correct te bekijken. ",googlePlay:"Please install Chrome from Google Play",appStore:"Please update iOS from the Settings App"},url:"https://browser-update.org/update-browser.html#nl",callToAction:"Update mijn browser nu ",close:"Sluiten"},pl:{outOfDate:"Twoja przeglądarka jest przestarzała!",update:{web:"Zaktualizuj swoją przeglądarkę, aby poprawnie wyświetlić tę stronę. ",googlePlay:"Please install Chrome from Google Play",appStore:"Please update iOS from the Settings App"},url:"https://browser-update.org/update-browser.html#pl",callToAction:"Zaktualizuj przeglądarkę już teraz",close:"Close"},pt:{outOfDate:"O seu browser está desatualizado!",update:{web:"Atualize o seu browser para ter uma melhor experiência e visualização deste site. ",googlePlay:"Please install Chrome from Google Play",appStore:"Please update iOS from the Settings App"},url:"https://browser-update.org/update-browser.html#pt",callToAction:"Atualize o seu browser agora",close:"Fechar"},ro:{outOfDate:"Browserul este învechit!",update:{web:"Actualizați browserul pentru a vizualiza corect acest site. ",googlePlay:"Please install Chrome from Google Play",appStore:"Please update iOS from the Settings App"},url:"https://browser-update.org/update-browser.html#",callToAction:"Actualizați browserul acum!",close:"Close"},ru:{outOfDate:"Ваш браузер устарел!",update:{web:"Обновите ваш браузер для правильного отображения этого сайта. ",googlePlay:"Please install Chrome from Google Play",appStore:"Please update iOS from the Settings App"},url:"https://browser-update.org/update-browser.html#ru",callToAction:"Обновить мой браузер ",close:"Закрыть"},si:{outOfDate:"Vaš brskalnik je zastarel!",update:{web:"Za pravilen prikaz spletne strani posodobite vaš brskalnik. ",googlePlay:"Please install Chrome from Google Play",appStore:"Please update iOS from the Settings App"},url:"https://browser-update.org/update-browser.html#si",callToAction:"Posodobi brskalnik ",close:"Zapri"},sv:{outOfDate:"Din webbläsare stödjs ej längre!",update:{web:"Uppdatera din webbläsare för att webbplatsen ska visas korrekt. ",googlePlay:"Please install Chrome from Google Play",appStore:"Please update iOS from the Settings App"},url:"https://browser-update.org/update-browser.html#",callToAction:"Uppdatera min webbläsare nu",close:"Stäng"},ua:{outOfDate:"Ваш браузер застарів!",update:{web:"Оновіть ваш браузер для правильного відображення цього сайта. ",googlePlay:"Please install Chrome from Google Play",appStore:"Please update iOS from the Settings App"},url:"https://browser-update.org/update-browser.html#ua",callToAction:"Оновити мій браузер ",close:"Закрити"}}},{}],4:[function(e,k,P){!function(t,p){"use strict";var c="function",e="undefined",o="model",i="name",a="type",r="vendor",s="version",l="architecture",n="console",d="mobile",u="tablet",w="smarttv",m="wearable",g={extend:function(e,o){var i={};for(var a in e)o[a]&&o[a].length%2==0?i[a]=o[a].concat(e[a]):i[a]=e[a];return i},has:function(e,o){return"string"==typeof e&&-1!==o.toLowerCase().indexOf(e.toLowerCase())},lowerize:function(e){return e.toLowerCase()},major:function(e){return"string"==typeof e?e.replace(/[^\d\.]/g,"").split(".")[0]:p},trim:function(e){return e.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")}},b={rgx:function(e,o){for(var i,a,t,r,s,l,n=0;n Date: Thu, 30 Apr 2020 11:16:27 +0200 Subject: [PATCH 009/459] Disable outdated-browser-rework - See https://github.com/mikemaccana/outdated-browser-rework/issues/57#issuecomment-620532590 --- src/components/Head.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/Head.tsx b/src/components/Head.tsx index db268be3c..a4659a732 100644 --- a/src/components/Head.tsx +++ b/src/components/Head.tsx @@ -80,8 +80,12 @@ const Head: React.FunctionComponent = ( {/* Detect outdated browser and display a popup about how to upgrade to a more recent browser/version */} {/* XXX See public/static/CDN/README.md */} -