mirror of
https://github.com/facebook/docusaurus.git
synced 2025-08-06 10:20:09 +02:00
fix(v2): baseUrl help banner should not be indexed by Google / SEO (#4125)
This commit is contained in:
parent
be7b5dca78
commit
9c4bf4e138
2 changed files with 83 additions and 70 deletions
|
@ -5,14 +5,91 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* 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 {useLocation} from 'react-router-dom';
|
||||||
|
|
||||||
import Head from '../exports/Head';
|
import Head from '../exports/Head';
|
||||||
|
|
||||||
import styles from './styles.module.css';
|
|
||||||
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
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)
|
// 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 hides if the external CSS is able to load successfully
|
||||||
// Note: it might create false positives (ie network failures): not a big deal
|
// 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},
|
siteConfig: {baseUrl, baseUrlIssueBanner},
|
||||||
} = useDocusaurusContext();
|
} = useDocusaurusContext();
|
||||||
const {pathname} = useLocation();
|
const {pathname} = useLocation();
|
||||||
|
useBannerRemover();
|
||||||
|
|
||||||
// returns true for the homepage during SRR
|
// returns true for the homepage during SRR
|
||||||
const isHomePage = pathname === baseUrl;
|
const isHomePage = pathname === baseUrl;
|
||||||
|
|
||||||
const shouldRender = baseUrlIssueBanner && isHomePage;
|
const enabled = baseUrlIssueBanner && isHomePage;
|
||||||
|
|
||||||
if (!shouldRender) {
|
return enabled ? <BaseUrlIssueBannerEnabled /> : null;
|
||||||
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>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,6 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.baseUrlIssueBanner {
|
:global(#docusaurus-base-url-issue-banner-container) {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue