Hydration mismatch when `<Scripts />` is mounted inside element
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 15.1k
- Forks
- 1.9k
- Avg merge
- 1d 20h
- Merged PRs (30d)
- 143
Description
Which project does this relate to?
Router
Describe the bug
my __root.tsx was like so:
function ShellComponent({ children }) {
return (
<html>
<head><HeadContent /></head>
<body>
<Providers>
<div className="layout">{children}</div>
</Providers>
</body>
</html>
)
}
function RootComponent() {
return (
<>
<Outlet />
<Scripts /> {/* ends up inside the layout div */}
</>
)
}
when <Scripts /> is mounted inside another element, it doesn't get hoisted correctly and results in a hydration mismatch. the docs say that <Scripts /> should be rendered as high up in the component tree as possible, not that it cannot reside inside another element.
Complete minimal reproducer
https://github.com/kylekz/router-script-repro
Steps to Reproduce the Bug
pnpm install && pnpm build && pnpm preview- open localhost:4173 with console open
- see react hydration error
Expected behavior
hydration error should not be happening
Screenshots or Videos
No response
Platform
- Router / Start Version: 1.170.17 / 1.168.27
- OS: Windows/WSL
- Browser: Chrome
- Browser Version: 150.0.7871.101
- Bundler: vite
- Bundler Version: 8.0.0
Additional context
initially i had this patched out with a bun patch in Asset.cjs like so:
if (!hydrated) {
if (attrs?.src) {
+ if (preventScriptHoist) {
+ return <script {...attrs} onLoad={noopScriptHandler} suppressHydrationWarning />
+ }
return <script {...attrs} suppressHydrationWarning />
}
but turns out it's just a case of moving <Scripts /> out of a nested element.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the mismatch with the linked kylekz/router-script-repro using pnpm install && pnpm build && pnpm preview, then inspect the mentioned Asset.cjs hydration and script-handling path. Done means mounting <Scripts /> inside the shown nested element no longer produces a React hydration error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react, typescript, vite
- Domain
- frontend, web-dev
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100