Skip to content

Commit

Permalink
fix(core): fix React hydration errors, change html minifier settings (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
slorber authored Dec 23, 2024
1 parent 2565601 commit f196a1e
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 34 deletions.
12 changes: 1 addition & 11 deletions argos/tests/screenshot.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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"',

Expand Down
17 changes: 13 additions & 4 deletions packages/docusaurus-bundler/src/minifyHtml.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -202,6 +209,7 @@ function CollapsibleBase({
className,
disableSSRStyle,
}: CollapsibleBaseProps) {
const isBrowser = useIsBrowser();
const collapsibleRef = useRef<HTMLElement>(null);

useCollapseAnimation({collapsibleRef, collapsed, animation});
Expand All @@ -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;
Expand Down
15 changes: 0 additions & 15 deletions website/_dogfooding/_pages tests/tabs-tests.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit f196a1e

Please sign in to comment.