TanStack / TanStack/router

SSR produces invalid HTML (Null Byte U+0000)

Open
#7,581 2 comments 1 reaction 0 assignees View on GitHub

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

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
  1. Create any TanStack Start project that uses SSR. This is easily reproducible with the start-basic example from this repo.
  2. Clone this example and install dependencies: https://github.com/TanStack/router/tree/main/examples/react/start-basic
  3. Build the project: npm run build
  4. Start the server: node .output/server/index.mjs
  5. Get the SSR-produced HTML: curl http://localhost:3000/ > index.html
  6. Visit the W3 markup validation service and upload the file. (https://validator.w3.org/#validate_by_upload)
  7. 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__.

Image
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.

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 examples/react/start-basic example and reproduce the issue with npm run build, node .output/server/index.mjs, and curl. Inspect the generated HTML around the "$tsr-stream-barrier" script tag and validate it; done means SSR output contains no U+0000 characters and no longer triggers the validator error.

Written by the indexing model from the issue text.

Assessment

Tech stack
react, typescript, vite
Domain
full-stack, web-dev
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.