vercel / next.js

The React Framework
https://nextjs.org
MIT License
124.72k stars 26.62k forks source link

[Next13] Using <header> tag while no <head> tag is present cause hydration errors. #41953

Open lelabo-m opened 1 year ago

lelabo-m commented 1 year ago

Verify canary release

Provide environment information

Operating System: Platform: linux Arch: x64 Version: #1 SMP Mon Sep 19 19:14:52 UTC 2022 Binaries: Node: 16.13.0 npm: 8.1.0 Yarn: N/A pnpm: 7.14.0 Relevant packages: next: 13.0.1-canary.0 eslint-config-next: 13.0.0 react: 18.2.0 react-dom: 18.2.0

What browser are you using? (if relevant)

Opera Gx / Chrome

How are you deploying your application? (if relevant)

pnpm run dev (next dev)

Describe the Bug

If you don't have a <head> tag in your RootLayout, using a header tag in any page (even when a head.tsx is present) will result in the hydration error below.

The error seems to be related to React Dev Tool extension.

react_devtools_backend.js:4026 Warning: Did not expect server HTML to contain a <script> in <header>.
    at header
    at div
    at div
    at InnerLayoutRouter (webpack-internal:///./node_modules/.pnpm/next@13.0.1-canary.0_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/layout-router.js:116:11)
    at RedirectErrorBoundary (webpack-internal:///./node_modules/.pnpm/next@13.0.1-canary.0_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/layout-router.js:281:9)
    at RedirectBoundary (webpack-internal:///./node_modules/.pnpm/next@13.0.1-canary.0_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/layout-router.js:288:11)
    at NotFoundErrorBoundary (webpack-internal:///./node_modules/.pnpm/next@13.0.1-canary.0_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/layout-router.js:317:9)
    at NotFoundBoundary (webpack-internal:///./node_modules/.pnpm/next@13.0.1-canary.0_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/layout-router.js:324:11)
    at LoadingBoundary (webpack-internal:///./node_modules/.pnpm/next@13.0.1-canary.0_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/layout-router.js:235:11)
    at ErrorBoundary (webpack-internal:///./node_modules/.pnpm/next@13.0.1-canary.0_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/error-boundary.js:40:11)
    at RenderFromTemplateContext (webpack-internal:///./node_modules/.pnpm/next@13.0.1-canary.0_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/render-from-template-context.js:12:34)
    at OuterLayoutRouter (webpack-internal:///./node_modules/.pnpm/next@13.0.1-canary.0_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/layout-router.js:17:11)
    at div
    at div
    at div
    at body
    at html
    at ReactDevOverlay (webpack-internal:///./node_modules/.pnpm/next@13.0.1-canary.0_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/react-dev-overlay/internal/ReactDevOverlay.js:53:9)
    at HotReload (webpack-internal:///./node_modules/.pnpm/next@13.0.1-canary.0_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/react-dev-overlay/hot-reloader-client.js:19:11)
    at Router (webpack-internal:///./node_modules/.pnpm/next@13.0.1-canary.0_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/app-router.js:73:11)
    at ErrorBoundaryHandler (webpack-internal:///./node_modules/.pnpm/next@13.0.1-canary.0_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/error-boundary.js:28:9)
    at ErrorBoundary (webpack-internal:///./node_modules/.pnpm/next@13.0.1-canary.0_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/error-boundary.js:40:11)
    at AppRouter
    at ServerRoot (webpack-internal:///./node_modules/.pnpm/next@13.0.1-canary.0_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/app-index.js:114:11)
    at RSCComponent
    at Root (webpack-internal:///./node_modules/.pnpm/next@13.0.1-canary.0_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/app-index.js:130:11)
overrideMethod @ react_devtools_backend.js:4026
print

Warning @ react-dom.development.js:94
error @ react-dom.development.js:68
warnForDeletedHydratableElement @ react-dom.development.js:10625
didNotHydrateInstance @ react-dom.development.js:13434
warnUnhydratedInstance @ react-dom.development.js:14443
warnIfUnhydratedTailNodes @ react-dom.development.js:14873
popHydrationState @ react-dom.development.js:14843
completeWork @ react-dom.development.js:25195
completeUnitOfWork @ react-dom.development.js:30669
performUnitOfWork @ react-dom.development.js:30555
workLoopConcurrent @ react-dom.development.js:30530
renderRootConcurrent @ react-dom.development.js:30469
performConcurrentWorkOnRoot @ react-dom.development.js:29657
workLoop @ index.js:11
flushWork @ index.js:11
performWorkUntilDeadline @ index.js:11
react_devtools_backend.js:4026 

Warning: An error occurred during hydration. The server HTML was replaced with client content in <#document>.
overrideMethod @ react_devtools_backend.js:4026
printWarning @ react-dom.development.js:94
error @ react-dom.development.js:68
errorHydratingContainer @ react-dom.development.js:13483
recoverFromConcurrentError @ react-dom.development.js:29767
performConcurrentWorkOnRoot @ react-dom.development.js:29670
workLoop @ index.js:11
flushWork @ index.js:11
performWorkUntilDeadline @ index.js:11
react-dom.development.js:14643

Uncaught Error: Hydration failed because the initial UI does not match what was rendered on the server.
    at throwOnHydrationMismatch (react-dom.development.js:14643:9)
    at popHydrationState (react-dom.development.js:14844:9)
    at completeWork (react-dom.development.js:25195:31)
    at completeUnitOfWork (react-dom.development.js:30669:16)
    at performUnitOfWork (react-dom.development.js:30555:5)
    at workLoopConcurrent (react-dom.development.js:30530:5)
    at renderRootConcurrent (react-dom.development.js:30469:7)
    at performConcurrentWorkOnRoot (react-dom.development.js:29657:38)
    at workLoop (index.js:11:3897)
    at flushWork (index.js:11:3606)
throwOnHydrationMismatch @ react-dom.development.js:14643
popHydrationState @ react-dom.development.js:14844
completeWork @ react-dom.development.js:25195
completeUnitOfWork @ react-dom.development.js:30669
performUnitOfWork @ react-dom.development.js:30555
workLoopConcurrent @ react-dom.development.js:30530
renderRootConcurrent @ react-dom.development.js:30469
performConcurrentWorkOnRoot @ react-dom.development.js:29657
workLoop @ index.js:11
flushWork @ index.js:11
performWorkUntilDeadline @ index.js:11
react-dom.development.js:14643

Uncaught Error: Hydration failed because the initial UI does not match what was rendered on the server.
    at throwOnHydrationMismatch (react-dom.development.js:14643:9)
    at tryToClaimNextHydratableInstance (react-dom.development.js:14693:7)
    at updateHostComponent (react-dom.development.js:22707:5)
    at beginWork (react-dom.development.js:24533:14)
    at beginWork$1 (react-dom.development.js:31612:14)
    at performUnitOfWork (react-dom.development.js:30544:12)
    at workLoopConcurrent (react-dom.development.js:30530:5)
    at renderRootConcurrent (react-dom.development.js:30469:7)
    at performConcurrentWorkOnRoot (react-dom.development.js:29657:38)
    at workLoop (index.js:11:3897)
throwOnHydrationMismatch @ react-dom.development.js:14643
tryToClaimNextHydratableInstance @ react-dom.development.js:14693
updateHostComponent @ react-dom.development.js:22707
beginWork @ react-dom.development.js:24533
beginWork$1 @ react-dom.development.js:31612
performUnitOfWork @ react-dom.development.js:30544
workLoopConcurrent @ react-dom.development.js:30530
renderRootConcurrent @ react-dom.development.js:30469
performConcurrentWorkOnRoot @ react-dom.development.js:29657
workLoop @ index.js:11
flushWork @ index.js:11
performWorkUntilDeadline @ index.js:11
2react-dom.development.js:14643

Uncaught Error: Hydration failed because the initial UI does not match what was rendered on the server.
    at throwOnHydrationMismatch (react-dom.development.js:14643:9)
    at popHydrationState (react-dom.development.js:14844:9)
    at completeWork (react-dom.development.js:25195:31)
    at completeUnitOfWork (react-dom.development.js:30669:16)
    at performUnitOfWork (react-dom.development.js:30555:5)
    at workLoopConcurrent (react-dom.development.js:30530:5)
    at renderRootConcurrent (react-dom.development.js:30469:7)
    at performConcurrentWorkOnRoot (react-dom.development.js:29657:38)
    at workLoop (index.js:11:3897)
    at flushWork (index.js:11:3606)
throwOnHydrationMismatch @ react-dom.development.js:14643
popHydrationState @ react-dom.development.js:14844
completeWork @ react-dom.development.js:25195
completeUnitOfWork @ react-dom.development.js:30669
performUnitOfWork @ react-dom.development.js:30555
workLoopConcurrent @ react-dom.development.js:30530
renderRootConcurrent @ react-dom.development.js:30469
performConcurrentWorkOnRoot @ react-dom.development.js:29657
workLoop @ index.js:11
flushWork @ index.js:11
performWorkUntilDeadline @ index.js:11
react-dom.development.js:14643

Uncaught Error: Hydration failed because the initial UI does not match what was rendered on the server.
    at throwOnHydrationMismatch (react-dom.development.js:14643:9)
    at tryToClaimNextHydratableInstance (react-dom.development.js:14693:7)
    at updateHostComponent (react-dom.development.js:22707:5)
    at beginWork (react-dom.development.js:24533:14)
    at beginWork$1 (react-dom.development.js:31612:14)
    at performUnitOfWork (react-dom.development.js:30544:12)
    at workLoopConcurrent (react-dom.development.js:30530:5)
    at renderRootConcurrent (react-dom.development.js:30469:7)
    at performConcurrentWorkOnRoot (react-dom.development.js:29657:38)
    at workLoop (index.js:11:3897)
throwOnHydrationMismatch @ react-dom.development.js:14643
tryToClaimNextHydratableInstance @ react-dom.development.js:14693
updateHostComponent @ react-dom.development.js:22707
beginWork @ react-dom.development.js:24533
beginWork$1 @ react-dom.development.js:31612
performUnitOfWork @ react-dom.development.js:30544
workLoopConcurrent @ react-dom.development.js:30530
renderRootConcurrent @ react-dom.development.js:30469
performConcurrentWorkOnRoot @ react-dom.development.js:29657
workLoop @ index.js:11
flushWork @ index.js:11
performWorkUntilDeadline @ index.js:11
react-dom.development.js:22654

Uncaught Error: There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.
    at updateHostRoot (react-dom.development.js:22654:57)
    at beginWork (react-dom.development.js:24516:14)
    at beginWork$1 (react-dom.development.js:31612:14)
    at performUnitOfWork (react-dom.development.js:30544:12)
    at workLoopSync (react-dom.development.js:30429:5)
    at renderRootSync (react-dom.development.js:30382:7)
    at recoverFromConcurrentError (react-dom.development.js:29771:20)
    at performConcurrentWorkOnRoot (react-dom.development.js:29670:22)
    at workLoop (index.js:11:3897)
    at flushWork (index.js:11:3606)

Expected Behavior

I expected:

Link to reproduction

https://github.com/vercel/next.js/tree/canary/examples/with-turbopack

To Reproduce

<header>
Test
</header>
tmilewski commented 1 year ago

I was having the exact same issue and can confirm that adding <head> to the root layout fixed it.

y-nk commented 1 year ago

@tmilewski thanks :) to be noted, still need to put an empty <head> tag in the root layout even if the head.tsx file exists... 🤷

lelabo-m commented 1 year ago

That's what I deduced but it's not clear right now in the doc that a head tag is required at anytime if you don't want to expect weird behaviors. In fact, in worked fine until I ran into this...

Xariwey commented 1 year ago

also removing the <head> tag while using a head.js/ts file will cause a layout shift, due to missing/broken styles