fix(v2): baseUrl help banner should not be indexed by Google / SEO (#4125)

This commit is contained in:
Sébastien Lorber 2021-01-29 18:00:13 +01:00 committed by GitHub
parent be7b5dca78
commit 9c4bf4e138
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 83 additions and 70 deletions

View file

@ -5,14 +5,91 @@
* 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';
import styles from './styles.module.css';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
// The critical CSS will hide the banner if it loads successfully!
import './styles.module.css';
const BannerContainerId = 'docusaurus-base-url-issue-banner-container';
const SuggestionContainerId =
'docusaurus-base-url-issue-banner-suggestion-container';
// 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
// - We can't SSR (or it would be indexed)
// - We can't CSR (as it means the baseurl is correct)
function createInlineHtmlBanner(baseUrl: string) {
return `
<div style="border: thick solid red; background-color: rgb(255, 230, 179); margin: 20px; padding: 20px; font-size: 20px;">
<p style="font-weight: bold; font-size: 30px;">Your Docusaurus site did not load properly.</p>
<p>A very common reason is a wrong site <a href="https://v2.docusaurus.io/docs/docusaurus.config.js/#baseurl" style="font-weight: bold;">baseUrl configuration</a>.</p>
<p>Current configured baseUrl = <span style="font-weight: bold; color: red;">${baseUrl}</span> ${
baseUrl === '/' ? ' (default value)' : ''
}</p>
<p>We suggest trying baseUrl = <span id="${SuggestionContainerId}" style="font-weight: bold; color: green;"></span></p>
</div>
`;
}
// fn needs to work for older browsers!
function createInlineScript(baseUrl: string) {
return `
function renderBanner() {
var banner = document.getElementById('${BannerContainerId}');
if (!banner) {
return;
}
var bannerHtml = ${JSON.stringify(createInlineHtmlBanner(baseUrl))
// See https://redux.js.org/recipes/server-rendering/#security-considerations
.replace(/</g, '\\\u003c')};
banner.innerHTML = bannerHtml;
var suggestionContainer = document.getElementById('${SuggestionContainerId}');
var actualHomePagePath = window.location.pathname;
var suggestedBaseUrl = actualHomePagePath.substr(-1) === '/'
? actualHomePagePath
: actualHomePagePath + '/';
suggestionContainer.innerHTML = suggestedBaseUrl;
}
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(() => {
const banner = document.getElementById(BannerContainerId);
if (banner) {
banner.remove();
}
}, []);
}
function BaseUrlIssueBannerEnabled() {
const {
siteConfig: {baseUrl},
} = useDocusaurusContext();
return (
<>
<Head>
<script>{createInlineScript(baseUrl)}</script>
</Head>
<div id={BannerContainerId} />
</>
);
}
// 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
// Note: it might create false positives (ie network failures): not a big deal
@ -23,76 +100,12 @@ export default function BaseUrlIssueBanner(): JSX.Element | null {
siteConfig: {baseUrl, baseUrlIssueBanner},
} = useDocusaurusContext();
const {pathname} = useLocation();
useBannerRemover();
// returns true for the homepage during SRR
const isHomePage = pathname === baseUrl;
const shouldRender = baseUrlIssueBanner && isHomePage;
const enabled = baseUrlIssueBanner && isHomePage;
if (!shouldRender) {
return null;
}
const BaseUrlIssueBannerContainerId = 'base-url-issue-banner-container';
return (
<>
<Head>
<script>
{`
document.addEventListener('DOMContentLoaded', function () {
var baseUrlSuggestion = document.getElementById(
'${BaseUrlIssueBannerContainerId}',
);
if (baseUrlSuggestion) {
var actualHomePagePath = window.location.pathname;
var suggestedBaseUrl = actualHomePagePath.substr(-1) === '/'
? actualHomePagePath
: actualHomePagePath + '/';
baseUrlSuggestion.innerHTML = suggestedBaseUrl;
}
});
`}
</script>
</Head>
<div
className={styles.baseUrlIssueBanner}
style={{
border: 'solid red thick',
backgroundColor: '#ffe6b3',
margin: 20,
padding: 20,
fontSize: 20,
}}>
<p
style={{
fontWeight: 'bold',
fontSize: 30,
}}>
Your Docusaurus site did not load properly.
</p>
<p>
A very common reason is a wrong site{' '}
<a
href="https://v2.docusaurus.io/docs/docusaurus.config.js/#baseurl"
style={{fontWeight: 'bold'}}>
baseUrl configuration
</a>
.
</p>
<p>
Current configured baseUrl ={' '}
<span style={{fontWeight: 'bold', color: 'red'}}>{baseUrl}</span>{' '}
{baseUrl === '/' ? ' (default value)' : ''}
</p>
<p>
We suggest trying baseUrl ={' '}
<span
style={{fontWeight: 'bold', color: 'green'}}
id={BaseUrlIssueBannerContainerId}
/>{' '}
</p>
</div>
</>
);
return enabled ? <BaseUrlIssueBannerEnabled /> : null;
}

View file

@ -5,6 +5,6 @@
* LICENSE file in the root directory of this source tree.
*/
.baseUrlIssueBanner {
:global(#docusaurus-base-url-issue-banner-container) {
display: none;
}