Which project does this relate to?
Router
Describe the bug
When TanStack Start/Router performs Server-Side Rendering, it produces multiple Null Bytes (U+0000) inside the "$tsr-stream-barrier" script tag of the server-generated HTML.
According to the HTML Living Standard specification, this character is forbidden from appearing in input streams. Specifically, section "13.2.2 Parse errors" lists the "control-character-in-input-stream" error (https://html.spec.whatwg.org/multipage/parsing.html#parse-errors).
It appears that browsers and other clients simply ignore this; however, when using an HTML validator for frontend projects (like we do at our company), this issue appears consistently. When validating ssr-produced HTML with https://validator.w3.org the error Saw U+0000 in stream comes up.
Complete minimal reproducer
https://github.com/TanStack/router/tree/main/examples/react/start-basic
Steps to Reproduce the Bug
- Create any TanStack Start project that uses SSR. This is easily reproducible with the
start-basic example from this repo.
- Clone this example and install dependencies:
https://github.com/TanStack/router/tree/main/examples/react/start-basic
- Build the project:
npm run build
- Start the server:
node .output/server/index.mjs
- Get the SSR-produced HTML:
curl http://localhost:3000/ > index.html
- Visit the W3 markup validation service and upload the file. (https://validator.w3.org/#validate_by_upload)
- Observe the error:
Saw U+0000 in stream.
This issue is NOT exclusive to the start-basic example. From my testing, it occurs every time Router/Start performs server-side rendering and includes the "$tsr-stream-barrier" script tag.
Expected behavior
I expect TanStack's SSR feature to abide by HTML standards and not produce HTML validation errors by default when validating SSR-produced HTML on services like https://validator.w3.org/.
Screenshots or Videos
Null Bytes occur in these 5 places. First occurence is after __root__.
Platform
- Router / Start Version: react-router: 1.170.15, react-start: 1.168.24
- OS: Debian Linux
- Browser: Firefox (not relevant to this issue)
- Browser Version: 150.0.1
- Bundler: vite
- Bundler Version: vite 8.0.14
(See the start-basic example)
Additional context
The null bytes seem to appear at five very specific locations in the script tag (as shown in the screenshot). From my testing, this behaviour (of exactly 5) is very consistent, no matter the project or served content.
Which project does this relate to?
Router
Describe the bug
When TanStack Start/Router performs Server-Side Rendering, it produces multiple Null Bytes (U+0000) inside the
"$tsr-stream-barrier"script tag of the server-generated HTML.According to the HTML Living Standard specification, this character is forbidden from appearing in input streams. Specifically, section "13.2.2 Parse errors" lists the "control-character-in-input-stream" error (https://html.spec.whatwg.org/multipage/parsing.html#parse-errors).
It appears that browsers and other clients simply ignore this; however, when using an HTML validator for frontend projects (like we do at our company), this issue appears consistently. When validating ssr-produced HTML with https://validator.w3.org the error
Saw U+0000 in streamcomes up.Complete minimal reproducer
https://github.com/TanStack/router/tree/main/examples/react/start-basic
Steps to Reproduce the Bug
start-basicexample from this repo.https://github.com/TanStack/router/tree/main/examples/react/start-basicnpm run buildnode .output/server/index.mjscurl http://localhost:3000/ > index.htmlSaw U+0000 in stream.This issue is NOT exclusive to the
start-basicexample. From my testing, it occurs every time Router/Start performs server-side rendering and includes the"$tsr-stream-barrier"script tag.Expected behavior
I expect TanStack's SSR feature to abide by HTML standards and not produce HTML validation errors by default when validating SSR-produced HTML on services like https://validator.w3.org/.
Screenshots or Videos
Null Bytes occur in these 5 places. First occurence is after
__root__.Platform
(See the
start-basicexample)Additional context
The null bytes seem to appear at five very specific locations in the script tag (as shown in the screenshot). From my testing, this behaviour (of exactly 5) is very consistent, no matter the project or served content.