mirror of
https://github.com/facebook/docusaurus.git
synced 2025-04-28 17:57:48 +02:00
fix(core): fix React hydration errors, change html minifier settings (#10786)
This commit is contained in:
parent
2565601af3
commit
f196a1eb29
4 changed files with 27 additions and 34 deletions
|
@ -131,21 +131,11 @@ function throwOnConsole(page: Page) {
|
|||
const typesToCheck = ['error', 'warning'];
|
||||
|
||||
const ignoreMessages = [
|
||||
// This mismatch warning looks like a React 18 bug to me
|
||||
'Warning: Prop `%s` did not match. Server: %s Client: %s%s className "null" ""',
|
||||
|
||||
// TODO this fetch error message is unexpected and should be fixed
|
||||
// it's already happening in main branch
|
||||
'Failed to load resource: the server responded with a status of 404 (Not Found)',
|
||||
|
||||
// TODO looks like a legit hydration bug to fix
|
||||
// on /blog/releases/2.4
|
||||
'Warning: Prop `%s` did not match. Server: %s Client: %s%s href "/docs" "/docs?docusaurus-theme=light"',
|
||||
'Warning: Prop `%s` did not match. Server: %s Client: %s%s href "/docs" "/docs?docusaurus-theme=dark"',
|
||||
// on /blog/releases/3.0
|
||||
'Warning: Prop `%s` did not match. Server: %s Client: %s%s href "/docs" "/docs?docusaurus-data-navbar=false&docusaurus-data-red-border"',
|
||||
// on /docs/styling-layout
|
||||
'Warning: Prop `%s` did not match. Server: %s Client: %s%s href "/docs" "/docs?docusaurus-data-navbar=false&docusaurus-data-red-border"',
|
||||
// TODO looks like legit hydration bugs to fix
|
||||
'Warning: Prop `%s` did not match. Server: %s Client: %s%s href "/docs/configuration" "/docs/configuration?docusaurus-theme=light"',
|
||||
'Warning: Prop `%s` did not match. Server: %s Client: %s%s href "/docs/configuration" "/docs/configuration?docusaurus-theme=dark"',
|
||||
|
||||
|
|
|
@ -47,9 +47,13 @@ async function getTerserMinifier(): Promise<HtmlMinifier> {
|
|||
minify: async function minifyHtmlWithTerser(html) {
|
||||
try {
|
||||
const code = await terserHtmlMinifier(html, {
|
||||
// When enabled => React hydration errors
|
||||
removeComments: false,
|
||||
removeRedundantAttributes: true,
|
||||
removeEmptyAttributes: true,
|
||||
removeRedundantAttributes: false,
|
||||
removeEmptyAttributes: false,
|
||||
sortAttributes: false,
|
||||
sortClassName: false,
|
||||
|
||||
removeScriptTypeAttributes: true,
|
||||
removeStyleLinkTypeAttributes: true,
|
||||
useShortDoctype: true,
|
||||
|
@ -84,8 +88,13 @@ async function getSwcMinifier(): Promise<HtmlMinifier> {
|
|||
sortSpaceSeparatedAttributeValues: false,
|
||||
sortAttributes: false,
|
||||
|
||||
removeRedundantAttributes: 'all',
|
||||
removeEmptyAttributes: true,
|
||||
// When enabled => hydration error for className={"yt-lite "}
|
||||
normalizeAttributes: false,
|
||||
// When enabled => hydration error for className=""
|
||||
removeEmptyAttributes: false,
|
||||
// When enabled => hydration error for <a target="_self">
|
||||
removeRedundantAttributes: 'none',
|
||||
|
||||
minifyJs: true,
|
||||
minifyJson: true,
|
||||
minifyCss: true,
|
||||
|
|
|
@ -15,7 +15,7 @@ import React, {
|
|||
type SetStateAction,
|
||||
type ReactNode,
|
||||
} from 'react';
|
||||
import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment';
|
||||
import useIsBrowser from '@docusaurus/useIsBrowser';
|
||||
import useIsomorphicLayoutEffect from '@docusaurus/useIsomorphicLayoutEffect';
|
||||
import {prefersReducedMotion} from '../../utils/accessibilityUtils';
|
||||
|
||||
|
@ -161,8 +161,15 @@ type CollapsibleElementType = React.ElementType<
|
|||
* Prevent hydration layout shift before animations are handled imperatively
|
||||
* with JS
|
||||
*/
|
||||
function getSSRStyle(collapsed: boolean) {
|
||||
if (ExecutionEnvironment.canUseDOM) {
|
||||
function getSSRStyle({
|
||||
collapsed,
|
||||
isBrowser,
|
||||
}: {
|
||||
collapsed: boolean;
|
||||
isBrowser: boolean;
|
||||
}) {
|
||||
// After hydration, styles are applied
|
||||
if (isBrowser) {
|
||||
return undefined;
|
||||
}
|
||||
return collapsed ? CollapsedStyles : ExpandedStyles;
|
||||
|
@ -202,6 +209,7 @@ function CollapsibleBase({
|
|||
className,
|
||||
disableSSRStyle,
|
||||
}: CollapsibleBaseProps) {
|
||||
const isBrowser = useIsBrowser();
|
||||
const collapsibleRef = useRef<HTMLElement>(null);
|
||||
|
||||
useCollapseAnimation({collapsibleRef, collapsed, animation});
|
||||
|
@ -211,7 +219,8 @@ function CollapsibleBase({
|
|||
// @ts-expect-error: the "too complicated type" is produced from
|
||||
// "CollapsibleElementType" being a huge union
|
||||
ref={collapsibleRef as RefObject<never>} // Refs are contravariant, which is not expressible in TS
|
||||
style={disableSSRStyle ? undefined : getSSRStyle(collapsed)}
|
||||
// Not even sure we need this SSRStyle anymore, try to remove it?
|
||||
style={disableSSRStyle ? undefined : getSSRStyle({collapsed, isBrowser})}
|
||||
onTransitionEnd={(e: React.TransitionEvent) => {
|
||||
if (e.propertyName !== 'height') {
|
||||
return;
|
||||
|
|
|
@ -6,21 +6,6 @@ import Tabs from '@theme/Tabs';
|
|||
import TabItem from '@theme/TabItem';
|
||||
```
|
||||
|
||||
## Tabs with dynamic default value
|
||||
|
||||
This can cause [bugs](https://github.com/facebook/react-native-website/issues/2771) when default value is different between SSR and client:
|
||||
|
||||
```mdx-code-block
|
||||
export const isMacOS = typeof window !== 'undefined' && navigator.platform.startsWith('Mac');
|
||||
|
||||
<BrowserWindow>
|
||||
<Tabs defaultValue={isMacOS ? "ios" : "android"}>
|
||||
<TabItem value="android" label="Android">Android content</TabItem>
|
||||
<TabItem value="ios" label="iOS">iOS content</TabItem>
|
||||
</Tabs>
|
||||
</BrowserWindow>
|
||||
```
|
||||
|
||||
## Tabs sync with different heights
|
||||
|
||||
```mdx-code-block
|
||||
|
|
Loading…
Add table
Reference in a new issue