From a51788a15f243a93cc685e65c9823aa0235b399e Mon Sep 17 00:00:00 2001 From: slorber Date: Mon, 1 Feb 2021 20:08:45 +0100 Subject: [PATCH 1/2] restore useBannerRemover --- .../baseUrlIssueBanner/BaseUrlIssueBanner.tsx | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/packages/docusaurus/src/client/baseUrlIssueBanner/BaseUrlIssueBanner.tsx b/packages/docusaurus/src/client/baseUrlIssueBanner/BaseUrlIssueBanner.tsx index c6bff4246c4b..b0f88e930baa 100644 --- a/packages/docusaurus/src/client/baseUrlIssueBanner/BaseUrlIssueBanner.tsx +++ b/packages/docusaurus/src/client/baseUrlIssueBanner/BaseUrlIssueBanner.tsx @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import React from 'react'; +import React, {useLayoutEffect} from 'react'; import {useLocation} from 'react-router-dom'; import Head from '../exports/Head'; @@ -27,7 +27,7 @@ const SuggestionContainerId = // - We can't CSR (as it means the baseurl is correct) function createInlineHtmlBanner(baseUrl: string) { return ` -
+

Your Docusaurus site did not load properly.

A very common reason is a wrong site baseUrl configuration.

Current configured baseUrl = ${baseUrl} ${ @@ -63,16 +63,29 @@ document.addEventListener('DOMContentLoaded', renderBanner); `; } +// Normally if the baseUrl is correct, the banner will already be hidden by the critical CSS +// But we can still remove it totally from the DOM if it's not useful anymore +// This is kind of a "double security" +// It can also prevent the banner to appear if the CSS fails to load due to some network error +function useBannerRemover() { + useLayoutEffect(() => { + document.addEventListener('DOMContentLoaded', () => { + document.getElementById(BannerContainerId)?.remove(); + }); + }, []); +} + function BaseUrlIssueBannerEnabled() { const { siteConfig: {baseUrl}, } = useDocusaurusContext(); + useBannerRemover(); + return ( <> -

); } From c8a4f7d3e0442e25869239e9a87c4d5a62cbfdd0 Mon Sep 17 00:00:00 2001 From: slorber Date: Tue, 2 Feb 2021 15:53:04 +0100 Subject: [PATCH 2/2] fix BaseUrlIssueBanner issues --- .../baseUrlIssueBanner/BaseUrlIssueBanner.tsx | 65 ++++++++++--------- website/dogfooding/clientModuleExample.ts | 4 +- 2 files changed, 37 insertions(+), 32 deletions(-) diff --git a/packages/docusaurus/src/client/baseUrlIssueBanner/BaseUrlIssueBanner.tsx b/packages/docusaurus/src/client/baseUrlIssueBanner/BaseUrlIssueBanner.tsx index b0f88e930baa..bd2cf3acaa5e 100644 --- a/packages/docusaurus/src/client/baseUrlIssueBanner/BaseUrlIssueBanner.tsx +++ b/packages/docusaurus/src/client/baseUrlIssueBanner/BaseUrlIssueBanner.tsx @@ -6,20 +6,23 @@ */ import React, {useLayoutEffect} from 'react'; -import {useLocation} from 'react-router-dom'; - -import Head from '../exports/Head'; - +import {useLocation} from '@docusaurus/router'; +import Head from '@docusaurus/Head'; +import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; -// The critical CSS will hide the banner if it loads successfully! +// Double-security: critical CSS will hide the banner if CSS can load! import './styles.module.css'; const BannerContainerId = 'docusaurus-base-url-issue-banner-container'; +const BannerId = 'docusaurus-base-url-issue-banner'; + const SuggestionContainerId = 'docusaurus-base-url-issue-banner-suggestion-container'; +const InsertBannerWindowAttribute = '__DOCUSAURUS_INSERT_BASEURL_BANNER'; + // It is important to not use React to render this banner // otherwise Google would index it, even if it's hidden with some critical CSS! // See https://github.com/facebook/docusaurus/issues/4028 @@ -27,7 +30,7 @@ const SuggestionContainerId = // - We can't CSR (as it means the baseurl is correct) function createInlineHtmlBanner(baseUrl: string) { return ` -
+

Your Docusaurus site did not load properly.

A very common reason is a wrong site baseUrl configuration.

Current configured baseUrl = ${baseUrl} ${ @@ -41,16 +44,24 @@ function createInlineHtmlBanner(baseUrl: string) { // fn needs to work for older browsers! function createInlineScript(baseUrl: string) { return ` -function renderBanner() { - var banner = document.getElementById('${BannerContainerId}'); - if (!banner) { +window['${InsertBannerWindowAttribute}'] = true; + +document.addEventListener('DOMContentLoaded', maybeInsertBanner); + +function maybeInsertBanner() { + var shouldInsert = window['${InsertBannerWindowAttribute}']; + shouldInsert && insertBanner(); +} + +function insertBanner() { + var bannerContainer = document.getElementById('${BannerContainerId}'); + if (!bannerContainer) { return; } var bannerHtml = ${JSON.stringify(createInlineHtmlBanner(baseUrl)) // See https://redux.js.org/recipes/server-rendering/#security-considerations .replace(/ { - document.addEventListener('DOMContentLoaded', () => { - document.getElementById(BannerContainerId)?.remove(); - }); - }, []); -} - function BaseUrlIssueBannerEnabled() { const { siteConfig: {baseUrl}, } = useDocusaurusContext(); - useBannerRemover(); + + // useLayoutEffect fires before DOMContentLoaded. + // It gives the opportunity to avoid inserting the banner in the first place + useLayoutEffect(() => { + window[InsertBannerWindowAttribute] = false; + }, []); return ( <> - - - + {!ExecutionEnvironment.canUseDOM && ( + + + + )} +

); } // We want to help the users with a bad baseUrl configuration (very common error) -// Help message is inlined, and hides if the external CSS is able to load successfully +// Help message is inlined, and hidden if JS or CSS is able to load // Note: it might create false positives (ie network failures): not a big deal // Note: we only inline this for the homepage to avoid polluting all the site's pages // See https://github.com/facebook/docusaurus/pull/3621 diff --git a/website/dogfooding/clientModuleExample.ts b/website/dogfooding/clientModuleExample.ts index 83b5c253ba74..f04597e22621 100644 --- a/website/dogfooding/clientModuleExample.ts +++ b/website/dogfooding/clientModuleExample.ts @@ -8,9 +8,9 @@ import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment'; export function onRouteUpdate({location}: {location: Location}) { - console.log('onRouteUpdate', {location}); + // console.log('onRouteUpdate', {location}); } if (ExecutionEnvironment.canUseDOM) { - console.log('client module example log'); + // console.log('client module example log'); }