Solid Start 2.0.0-rc.0: a head() `scripts` entry is SSR’d with a hydration key that is never claimed
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?
Start
Describe the bug
A script declared through a route's head() is server-rendered with an _hk hydration key that the client never claims, so every page load logs:
Hydration completed with 1 unclaimed server-rendered node(s):
<script _hk="0000010101149d40">window.__headScriptRan = true;</script>
The script itself works — it executes at parse time. title / meta / link entries from the same head() are claimed normally; only scripts entries are left over, one unclaimed node per script.
Nothing downstream breaks in the reproducer (the body hydrates and stays reactive), so this is cosmetic on its own. It matters because unclaimed-node warnings are how real hydration desyncs surface in Solid — a permanent benign one trains you to ignore the signal.
Complete minimal reproducer
https://github.com/TylerRick/tanstack-solid-head-scripts-repro
Steps to Reproduce the Bug or Issue
pnpm installpnpm dev- Open http://localhost:5587 with the browser console visible — the warning above is there on load.
- Controls, both in
src/routes/__root.tsx: delete thescriptsentry and the warning goes away; add a second script and there are two unclaimed nodes.
Expected behavior
Head scripts are either claimed at hydration like the other head entries, or rendered without a hydration key — so an app that uses head().scripts doesn't report unclaimed server-rendered nodes on every load.
Screenshots or Videos
No response
Platform
- Router / Start Version:
@tanstack/solid-startand@tanstack/solid-router2.0.0-rc.0,@tanstack/router-core1.171.16 - solid-js /
@solidjs/web: 2.0.0-rc.0 - OS: Linux
- Browser: Chromium 141
- Bundler: vite 8.2.1 (vite-plugin-solid 3.0.0-next.27)
Additional context
Workaround we're using: render inline head scripts as direct JSX inside <head> in the root route's shellComponent instead of declaring them through head().
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
Start with the linked reproducer and its src/routes/__root.tsx, where the head() scripts entry can be toggled and the hydration warning observed. Trace how head scripts are server-rendered and claimed during hydration; done means the warning is absent while title, meta, link, script execution, and body reactivity continue to work.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 64/100