TanStack / TanStack/router

Solid Start 2.0.0-rc.0: a head() `scripts` entry is SSR’d with a hydration key that is never claimed

Open
#8,107 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

information needed
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
  1. pnpm install
  2. pnpm dev
  3. Open http://localhost:5587 with the browser console visible — the warning above is there on load.
  4. Controls, both in src/routes/__root.tsx: delete the scripts entry 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-start and @tanstack/solid-router 2.0.0-rc.0, @tanstack/router-core 1.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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.