From f412666120e24b924c6f2b54d04915a8fa1aa8c9 Mon Sep 17 00:00:00 2001 From: Zack Tanner <1939140+ztanner@users.noreply.github.com> Date: Mon, 3 Feb 2025 14:11:18 -0800 Subject: [PATCH] [DevOverlay] cleanup hydration error UI (#75499) --- .../client/components/is-hydration-error.ts | 2 +- .../internal/container/errors.tsx | 3 +++ .../component-stack-pseudo-html.tsx | 25 +++++++------------ .../container/runtime-error/index.tsx | 6 ++--- .../internal/icons/collapse-icon.tsx | 17 ++++++------- .../acceptance-app/hydration-error.test.ts | 16 ++++++------ .../acceptance/hydration-error.test.ts | 14 +++++------ 7 files changed, 38 insertions(+), 45 deletions(-) diff --git a/packages/next/src/client/components/is-hydration-error.ts b/packages/next/src/client/components/is-hydration-error.ts index a066a03b68a4a..2ce93033a5baa 100644 --- a/packages/next/src/client/components/is-hydration-error.ts +++ b/packages/next/src/client/components/is-hydration-error.ts @@ -3,7 +3,7 @@ import isError from '../../lib/is-error' const hydrationErrorRegex = /hydration failed|while hydrating|content does not match|did not match|HTML didn't match/i -const reactUnifiedMismatchWarning = `Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used` +const reactUnifiedMismatchWarning = `Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used:` const reactHydrationStartMessages = [ reactUnifiedMismatchWarning, diff --git a/packages/next/src/client/components/react-dev-overlay/_experimental/internal/container/errors.tsx b/packages/next/src/client/components/react-dev-overlay/_experimental/internal/container/errors.tsx index c1ecae8549949..4d727e4771126 100644 --- a/packages/next/src/client/components/react-dev-overlay/_experimental/internal/container/errors.tsx +++ b/packages/next/src/client/components/react-dev-overlay/_experimental/internal/container/errors.tsx @@ -267,4 +267,7 @@ export const styles = css` .error-overlay-notes-container { padding: 0 var(--size-4); } + .error-overlay-notes-container p { + white-space: pre-wrap; + } ` diff --git a/packages/next/src/client/components/react-dev-overlay/_experimental/internal/container/runtime-error/component-stack-pseudo-html.tsx b/packages/next/src/client/components/react-dev-overlay/_experimental/internal/container/runtime-error/component-stack-pseudo-html.tsx index 8f9de819d59b0..f22c56d2d00dc 100644 --- a/packages/next/src/client/components/react-dev-overlay/_experimental/internal/container/runtime-error/component-stack-pseudo-html.tsx +++ b/packages/next/src/client/components/react-dev-overlay/_experimental/internal/container/runtime-error/component-stack-pseudo-html.tsx @@ -304,15 +304,13 @@ export function PseudoHtmlDiff({ return (
{htmlComponents}
@@ -371,6 +369,7 @@ export const PSEUDO_HTML_DIFF_STYLES = css`
}
[data-nextjs-container-errors-pseudo-html-collapse] {
all: unset;
+ padding: var(--size-2);
&:focus {
outline: none;
}
@@ -393,16 +392,10 @@ export const PSEUDO_HTML_DIFF_STYLES = css`
[data-nextjs-container-errors-pseudo-html--tag-adjacent='false'] {
color: var(--color-accents-1);
}
-
- [data-nextjs-container-errors-pseudo-html] > span {
- display: block;
- height: var(--size-5);
- }
[data-nextjs-container-errors-pseudo-html] > pre > code > span {
display: block;
- height: var(--size-5);
+ padding: var(--size-1) var(--size-4);
}
-
.nextjs__container_errors__component-stack {
margin: 0;
}
diff --git a/packages/next/src/client/components/react-dev-overlay/_experimental/internal/container/runtime-error/index.tsx b/packages/next/src/client/components/react-dev-overlay/_experimental/internal/container/runtime-error/index.tsx
index 9d57674c61d31..578b09be0b3c6 100644
--- a/packages/next/src/client/components/react-dev-overlay/_experimental/internal/container/runtime-error/index.tsx
+++ b/packages/next/src/client/components/react-dev-overlay/_experimental/internal/container/runtime-error/index.tsx
@@ -8,7 +8,7 @@ import type { ReadyRuntimeError } from '../../../../internal/helpers/get-error-b
export type RuntimeErrorProps = { error: ReadyRuntimeError }
export function RuntimeError({ error }: RuntimeErrorProps) {
- const { firstFrame } = useMemo(() => {
+ const firstFrame = useMemo(() => {
const firstFirstPartyFrameIndex = error.frames.findIndex(
(entry) =>
!entry.ignored &&
@@ -16,9 +16,7 @@ export function RuntimeError({ error }: RuntimeErrorProps) {
Boolean(entry.originalStackFrame)
)
- return {
- firstFrame: error.frames[firstFirstPartyFrameIndex] ?? null,
- }
+ return error.frames[firstFirstPartyFrameIndex] ?? null
}, [error.frames])
return (
diff --git a/packages/next/src/client/components/react-dev-overlay/_experimental/internal/icons/collapse-icon.tsx b/packages/next/src/client/components/react-dev-overlay/_experimental/internal/icons/collapse-icon.tsx
index 8dab41204c571..592d18cc6e706 100644
--- a/packages/next/src/client/components/react-dev-overlay/_experimental/internal/icons/collapse-icon.tsx
+++ b/packages/next/src/client/components/react-dev-overlay/_experimental/internal/icons/collapse-icon.tsx
@@ -3,21 +3,20 @@ export function CollapseIcon({ collapsed }: { collapsed?: boolean } = {}) {
)
}
diff --git a/test/development/acceptance-app/hydration-error.test.ts b/test/development/acceptance-app/hydration-error.test.ts
index 108c2e8fe5364..5122691ee6746 100644
--- a/test/development/acceptance-app/hydration-error.test.ts
+++ b/test/development/acceptance-app/hydration-error.test.ts
@@ -76,7 +76,7 @@ describe('Error overlay for hydration errors in App router', () => {
expect(await getRedboxTotalErrorCount(browser)).toBe(1)
expect(await session.getRedboxDescription()).toMatchInlineSnapshot(
- `"Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used"`
+ `"Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used:"`
)
expect(await session.getRedboxDescriptionWarning()).toMatchInlineSnapshot(`
@@ -173,7 +173,7 @@ describe('Error overlay for hydration errors in App router', () => {
}
expect(await session.getRedboxDescription()).toMatchInlineSnapshot(
- `"Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used"`
+ `"Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used:"`
)
})
@@ -209,7 +209,7 @@ describe('Error overlay for hydration errors in App router', () => {
expect(pseudoHtml).toMatchInlineSnapshot(`"- className="server-html""`)
expect(await session.getRedboxDescription()).toMatchInlineSnapshot(
- `"Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used"`
+ `"Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used:"`
)
})
@@ -259,7 +259,7 @@ describe('Error overlay for hydration errors in App router', () => {
}
expect(await session.getRedboxDescription()).toMatchInlineSnapshot(
- `"Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used"`
+ `"Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used:"`
)
})
@@ -304,7 +304,7 @@ describe('Error overlay for hydration errors in App router', () => {
}
expect(await session.getRedboxDescription()).toMatchInlineSnapshot(
- `"Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used"`
+ `"Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used:"`
)
})
@@ -330,7 +330,7 @@ describe('Error overlay for hydration errors in App router', () => {
expect(await getRedboxTotalErrorCount(browser)).toBe(1)
expect(await session.getRedboxDescription()).toMatchInlineSnapshot(
- `"Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used"`
+ `"Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used:"`
)
const pseudoHtml = await session.getRedboxComponentStack()
@@ -380,7 +380,7 @@ describe('Error overlay for hydration errors in App router', () => {
// FIXME: Should also have "text nodes cannot be a child of tr"
expect(await session.getRedboxDescription()).toMatchInlineSnapshot(
- `"Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used"`
+ `"Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used:"`
)
const pseudoHtml = await session.getRedboxComponentStack()
@@ -504,7 +504,7 @@ describe('Error overlay for hydration errors in App router', () => {
}
expect(await session.getRedboxDescription()).toMatchInlineSnapshot(
- `"Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used"`
+ `"Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used:"`
)
})
diff --git a/test/development/acceptance/hydration-error.test.ts b/test/development/acceptance/hydration-error.test.ts
index 188a6209d616b..eb5a1da8b25e2 100644
--- a/test/development/acceptance/hydration-error.test.ts
+++ b/test/development/acceptance/hydration-error.test.ts
@@ -83,7 +83,7 @@ describe('Error overlay for hydration errors in Pages router', () => {
)
} else {
expect(await session.getRedboxDescription()).toMatchInlineSnapshot(
- `"Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used"`
+ `"Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used:"`
)
}
@@ -255,7 +255,7 @@ describe('Error overlay for hydration errors in Pages router', () => {
)
} else {
expect(await session.getRedboxDescription()).toMatchInlineSnapshot(
- `"Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used"`
+ `"Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used:"`
)
}
})
@@ -342,7 +342,7 @@ describe('Error overlay for hydration errors in Pages router', () => {
)
} else {
expect(await session.getRedboxDescription()).toMatchInlineSnapshot(
- `"Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used"`
+ `"Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used:"`
)
}
})
@@ -412,7 +412,7 @@ describe('Error overlay for hydration errors in Pages router', () => {
)
} else {
expect(await session.getRedboxDescription()).toMatchInlineSnapshot(
- `"Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used"`
+ `"Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used:"`
)
}
})
@@ -442,7 +442,7 @@ describe('Error overlay for hydration errors in Pages router', () => {
)
} else {
expect(await session.getRedboxDescription()).toMatchInlineSnapshot(
- `"Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used"`
+ `"Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used:"`
)
}
@@ -532,7 +532,7 @@ describe('Error overlay for hydration errors in Pages router', () => {
)
} else {
expect(await session.getRedboxDescription()).toMatchInlineSnapshot(
- `"Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used"`
+ `"Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used:"`
)
}
@@ -691,7 +691,7 @@ describe('Error overlay for hydration errors in Pages router', () => {
)
} else {
expect(await session.getRedboxDescription()).toMatchInlineSnapshot(
- `"Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used"`
+ `"Hydration failed because the server rendered HTML didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used:"`
)
}
})