Skip to content

Conversation

@birkskyum
Copy link
Member

@birkskyum birkskyum commented Nov 19, 2025

Fixes #5898

Summary by CodeRabbit

  • Bug Fixes
    • Fixed Script component rendering unnecessary empty script tags during client-side hydration, improving DOM consistency between server and client renders.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 19, 2025

Walkthrough

The Script component in the Solid router's Asset file now returns null on client-side mounting when content is not server-rendered, replacing the previous empty script tag. This change addresses hydration mismatch errors without altering server-side logic or other code paths.

Changes

Cohort / File(s) Summary
Solid router Script component hydration fix
packages/solid-router/src/Asset.tsx
Modified client-side rendering logic to return null instead of an empty script element when content is not server-rendered, fixing hydration behavior.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • Verify the hydration mismatch is resolved with the null return instead of empty <script/> tag
  • Confirm server-side rendering and script creation logic remain unaffected
  • Check for any downstream impacts on components that depend on this Script behavior

Possibly related PRs

Suggested reviewers

  • brenelz
  • schiller-manuel

Poem

🐰 A script tag once lingered empty and lost,
Hydration mismatch? A hydration cost!
But now we return nothing, lean and light,
The client and server? They're one again, tight! ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies a specific hydration regression fix for solid-start version 1.136.9, directly matching the PR's objective.
Linked Issues check ✅ Passed The code change (rendering null instead of empty script tag on client-side mounting) directly addresses the hydration mismatch regression reported in issue #5898.
Out of Scope Changes check ✅ Passed The modification to Asset.tsx is narrowly scoped to fixing hydration behavior by adjusting client-side Script component rendering, directly aligned with the linked issue.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix(solid-start)--fix-hydration-regression-in-1.136.9

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@nx-cloud
Copy link

nx-cloud bot commented Nov 19, 2025

View your CI Pipeline Execution ↗ for commit ec9247a

Command Status Duration Result
nx affected --targets=test:eslint,test:unit,tes... ✅ Succeeded 9m 8s View ↗
nx run-many --target=build --exclude=examples/*... ✅ Succeeded 29s View ↗

☁️ Nx Cloud last updated this comment at 2025-11-19 12:32:02 UTC

@pkg-pr-new
Copy link

pkg-pr-new bot commented Nov 19, 2025

More templates

@tanstack/arktype-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/arktype-adapter@5903

@tanstack/directive-functions-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/directive-functions-plugin@5903

@tanstack/eslint-plugin-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/eslint-plugin-router@5903

@tanstack/history

npm i https://pkg.pr.new/TanStack/router/@tanstack/history@5903

@tanstack/nitro-v2-vite-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/nitro-v2-vite-plugin@5903

@tanstack/react-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router@5903

@tanstack/react-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router-devtools@5903

@tanstack/react-router-ssr-query

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-router-ssr-query@5903

@tanstack/react-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start@5903

@tanstack/react-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-client@5903

@tanstack/react-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/react-start-server@5903

@tanstack/router-cli

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-cli@5903

@tanstack/router-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-core@5903

@tanstack/router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-devtools@5903

@tanstack/router-devtools-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-devtools-core@5903

@tanstack/router-generator

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-generator@5903

@tanstack/router-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-plugin@5903

@tanstack/router-ssr-query-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-ssr-query-core@5903

@tanstack/router-utils

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-utils@5903

@tanstack/router-vite-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/router-vite-plugin@5903

@tanstack/server-functions-plugin

npm i https://pkg.pr.new/TanStack/router/@tanstack/server-functions-plugin@5903

@tanstack/solid-router

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router@5903

@tanstack/solid-router-devtools

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router-devtools@5903

@tanstack/solid-router-ssr-query

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-router-ssr-query@5903

@tanstack/solid-start

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start@5903

@tanstack/solid-start-client

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-client@5903

@tanstack/solid-start-server

npm i https://pkg.pr.new/TanStack/router/@tanstack/solid-start-server@5903

@tanstack/start-client-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-client-core@5903

@tanstack/start-plugin-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-plugin-core@5903

@tanstack/start-server-core

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-server-core@5903

@tanstack/start-static-server-functions

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-static-server-functions@5903

@tanstack/start-storage-context

npm i https://pkg.pr.new/TanStack/router/@tanstack/start-storage-context@5903

@tanstack/valibot-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/valibot-adapter@5903

@tanstack/virtual-file-routes

npm i https://pkg.pr.new/TanStack/router/@tanstack/virtual-file-routes@5903

@tanstack/zod-adapter

npm i https://pkg.pr.new/TanStack/router/@tanstack/zod-adapter@5903

commit: ec9247a

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3a97163 and ec9247a.

📒 Files selected for processing (1)
  • packages/solid-router/src/Asset.tsx (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: nlynzaad
Repo: TanStack/router PR: 5732
File: packages/start-client-core/src/client/hydrateStart.ts:6-9
Timestamp: 2025-11-02T16:16:24.898Z
Learning: In packages/start-client-core/src/client/hydrateStart.ts, the `import/no-duplicates` ESLint disable is necessary for imports from `#tanstack-router-entry` and `#tanstack-start-entry` because both aliases resolve to the same placeholder file (`fake-start-entry.js`) in package.json during static analysis, even though they resolve to different files at runtime.
📚 Learning: 2025-11-02T16:16:24.898Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5732
File: packages/start-client-core/src/client/hydrateStart.ts:6-9
Timestamp: 2025-11-02T16:16:24.898Z
Learning: In packages/start-client-core/src/client/hydrateStart.ts, the `import/no-duplicates` ESLint disable is necessary for imports from `#tanstack-router-entry` and `#tanstack-start-entry` because both aliases resolve to the same placeholder file (`fake-start-entry.js`) in package.json during static analysis, even though they resolve to different files at runtime.

Applied to files:

  • packages/solid-router/src/Asset.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Preview
  • GitHub Check: Test
🔇 Additional comments (1)
packages/solid-router/src/Asset.tsx (1)

128-128: Let me examine the Asset.tsx file directly to understand the full context of this change:

Based on my research into Solid.js's isServer property, which is a non-reactive flag exported from solid-js/web that indicates whether code is executing on the server, I can now provide a definitive assessment:

The original review comment's concern about hydration mismatch appears to be based on a misunderstanding. When server and client render using isServer, they are separate reactive contexts, so the value change won't be detected on hydration. This means both server and client execute the same conditional logic—when the server evaluates isServer to true and returns null, the client will evaluate isServer to false but will execute the same logic path that also returns null during hydration. Since both produce the same DOM output, there is no mismatch.

The change to return null on line 128 (instead of an empty <script></script>) is correct because:

  • It matches the server-side behavior when there is no src attribute and no string children
  • Both client and server use identical conditional logic based on isServer
  • The hydration context receives matching DOM from both sides

})

if (!router.isServer) {
// render an empty script on the client just to avoid hydration errors
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Update the comment to match the new behavior.

The comment states "render an empty script on the client just to avoid hydration errors", but the code now returns null instead of an empty script tag.

Apply this diff to update the comment:

-    // render an empty script on the client just to avoid hydration errors
+    // render nothing on the client to match server-side behavior and avoid hydration errors
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// render an empty script on the client just to avoid hydration errors
// render nothing on the client to match server-side behavior and avoid hydration errors
🤖 Prompt for AI Agents
In packages/solid-router/src/Asset.tsx around line 127, update the inline
comment which currently reads "render an empty script on the client just to
avoid hydration errors" to reflect the new behavior: the component now returns
null on the client to avoid hydration errors; change the comment to something
like "return null on the client to avoid hydration errors" so it matches the
code.

@birkskyum birkskyum merged commit e93b712 into main Nov 19, 2025
6 checks passed
@birkskyum birkskyum deleted the fix(solid-start)--fix-hydration-regression-in-1.136.9 branch November 19, 2025 12:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[SOLID] tanstack start 1.136.11 (looks like 1.136.9?) causes hydration errors

2 participants