Skip to content

perf(history): use lightweight history for server rendering - #8354

Merged
Sheraff merged 1 commit into
mainfrom
codex/server-history
Sep 11, 2026
Merged

Sheraff merged 1 commit into
mainfrom
codex/server-history

Conversation

@Sheraff

@Sheraff Sheraff commented Sep 11, 2026 •

Copy link
Copy Markdown
Collaborator

🎯 Changes

SSR handlers currently allocate a full memory history for each request, including a navigation stack and per-instance callbacks. Add createServerHistory to @tanstack/history and use it in Router and Start SSR handlers. It keeps one request location, shares methods, and uses the same href normalization as browser history.

Server calls to navigate, buildAndCommitLocation, and commitLocation now resolve without changing the location or starting another load. HTTP redirects continue to use redirect(). These guards use the existing isServer flag, preserving client navigation behavior.

Includes regression coverage for href normalization, request isolation, no-op server navigation, HTTP redirects, and client push/replace behavior, plus SSR documentation updates.

Previously validated locally: 3,405 tests passed across history, Router Core, and Start server, along with their type, lint, and package build checks. No additional checks were run when opening this PR.

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested code changes locally with the relevant test commands, or tests do not apply to this pull request.
  • I fully understand the code in this pull request, including any code generated with AI assistance.

🚀 Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release).

Summary by CodeRabbit

  • New Features

    • Added lightweight server-side history for SSR requests, preserving the request URL without maintaining navigation history.
    • Added createServerHistory for server request handlers.
    • Server-side navigation is now safely ignored; redirects continue to produce HTTP redirect responses.
    • Server href normalization now matches browser history, including protocol-relative URLs and control characters.
  • Documentation

    • Updated SSR and history guides with server-history behavior and redirect guidance.
  • Bug Fixes

    • Prevented server-side navigation during route loading from changing URLs or triggering unintended loaders.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 11, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-11T08:44:50.907826Z 7649ecf PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@coderabbitai

coderabbitai Bot commented Sep 11, 2026 •

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 4654e415-212f-4b9a-922c-cf9657b97613

📥 Commits

Reviewing files that changed from the base of the PR and between 6494e75 and 7649ecf.

📒 Files selected for processing (11)
  • .changeset/sad-pans-design.md
  • docs/router/guide/history-types.md
  • docs/router/guide/ssr.md
  • packages/history/src/index.ts
  • packages/history/tests/createServerHistory.test.ts
  • packages/router-core/src/router.ts
  • packages/router-core/src/ssr/createRequestHandler.ts
  • packages/router-core/tests/document-navigation.test.ts
  • packages/router-core/tests/server-history.test.ts
  • packages/start-server-core/src/createStartHandler.ts
  • packages/start-server-core/tests/createStartHandler.test.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review.


📝 Walkthrough

Walkthrough

SSR now uses fixed request-scoped server history. Server navigation methods are no-ops. Router and Start handlers use the new history, with tests and documentation covering normalization, redirects, and unchanged request locations.

Changes

SSR server navigation

Layer / File(s) Summary
Server history implementation
packages/history/src/index.ts, packages/history/tests/createServerHistory.test.ts
Adds createServerHistory with a fixed location, normalized hrefs, no-op navigation, isolated state, and empty blocker collections.
Server navigation guards
packages/router-core/src/router.ts, packages/router-core/tests/server-history.test.ts, packages/router-core/tests/document-navigation.test.ts
Server-side navigation entry points return without building, loading, committing, or changing history. Redirect responses remain supported.
SSR handler integration and documentation
packages/router-core/src/ssr/createRequestHandler.ts, packages/start-server-core/src/createStartHandler.ts, packages/start-server-core/tests/createStartHandler.test.ts, docs/router/guide/history-types.md, docs/router/guide/ssr.md, .changeset/sad-pans-design.md
SSR handlers use server history from the request URL. Tests and documentation describe fixed locations, no-op navigation, and redirect usage.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant SSRHandler
  participant ServerHistory
  participant RouterCore
  participant HTTPResponse
  SSRHandler->>ServerHistory: createServerHistory(request href)
  SSRHandler->>RouterCore: load request
  RouterCore->>ServerHistory: navigation request
  ServerHistory-->>RouterCore: retain fixed request location
  RouterCore->>HTTPResponse: return redirect response when redirect() is thrown
Loading

Merge Risk: ⚪ Minimal · up to 7649e

SSR navigation preserves the request location while redirects continue to return HTTP redirect responses. No actionable merge risk remains.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 5 functions across 8 files. (3 skipped: 3… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description check ✅ Passed The description explains the lightweight server history change, SSR integration, server navigation guards, redirects, tests, documentation updates, and release impact. All required template sections a…
Title check ✅ Passed The title clearly and concisely identifies the main change: using lightweight history for server rendering.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 5 functions across 8 files. (3 skipped: 3 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/server-history

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.

@nx-cloud

nx-cloud Bot commented Sep 11, 2026 •

Copy link
Copy Markdown
Contributor

View your CI Pipeline Execution ↗ for commit 7649ecf

Command Status Duration Result
nx affected --targets=test:eslint,test:unit,tes... ✅ Succeeded 4m 56s View ↗

☁️ Nx Cloud last updated this comment at 2026-09-11 09:03:55 UTC

@github-actions

Copy link
Copy Markdown
Contributor

🚀 Changeset Version Preview

3 package(s) bumped directly, 21 bumped as dependents.

🟩 Patch bumps

Package Version Reason
@tanstack/history 1.162.3 → 1.162.4 Changeset
@tanstack/router-core 1.171.29 → 1.171.30 Changeset
@tanstack/start-server-core 1.169.34 → 1.169.35 Changeset
@tanstack/react-router 1.170.35 → 1.170.36 Dependent
@tanstack/react-start 1.168.52 → 1.168.53 Dependent
@tanstack/react-start-client 1.168.33 → 1.168.34 Dependent
@tanstack/react-start-rsc 0.1.51 → 0.1.52 Dependent
@tanstack/react-start-server 1.167.40 → 1.167.41 Dependent
@tanstack/router-cli 1.167.35 → 1.167.36 Dependent
@tanstack/router-generator 1.167.35 → 1.167.36 Dependent
@tanstack/router-plugin 1.168.37 → 1.168.38 Dependent
@tanstack/router-vite-plugin 1.167.37 → 1.167.38 Dependent
@tanstack/solid-router 1.170.33 → 1.170.34 Dependent
@tanstack/solid-start 1.168.50 → 1.168.51 Dependent
@tanstack/solid-start-client 1.168.32 → 1.168.33 Dependent
@tanstack/solid-start-server 1.167.39 → 1.167.40 Dependent
@tanstack/start-client-core 1.170.29 → 1.170.30 Dependent
@tanstack/start-plugin-core 1.171.42 → 1.171.43 Dependent
@tanstack/start-static-server-functions 1.167.34 → 1.167.35 Dependent
@tanstack/start-storage-context 1.167.31 → 1.167.32 Dependent
@tanstack/vue-router 1.170.32 → 1.170.33 Dependent
@tanstack/vue-start 1.168.49 → 1.168.50 Dependent
@tanstack/vue-start-client 1.167.35 → 1.167.36 Dependent
@tanstack/vue-start-server 1.167.39 → 1.167.40 Dependent

@github-actions

Copy link
Copy Markdown
Contributor

Bundle Size Benchmarks

This pull request does not affect bundle size in any measured scenario.

@pkg-pr-new

pkg-pr-new Bot commented Sep 11, 2026

Copy link
Copy Markdown
More templates

@tanstack/arktype-adapter

npm i https://pkg.pr.new/@tanstack/arktype-adapter@8354

@tanstack/eslint-plugin-router

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

@tanstack/eslint-plugin-start

npm i https://pkg.pr.new/@tanstack/eslint-plugin-start@8354

@tanstack/history

npm i https://pkg.pr.new/@tanstack/history@8354

@tanstack/nitro-v2-vite-plugin

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

@tanstack/react-router

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

@tanstack/react-router-devtools

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

@tanstack/react-router-ssr-query

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

@tanstack/react-start

npm i https://pkg.pr.new/@tanstack/react-start@8354

@tanstack/react-start-client

npm i https://pkg.pr.new/@tanstack/react-start-client@8354

@tanstack/react-start-rsc

npm i https://pkg.pr.new/@tanstack/react-start-rsc@8354

@tanstack/react-start-server

npm i https://pkg.pr.new/@tanstack/react-start-server@8354

@tanstack/router-cli

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

@tanstack/router-core

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

@tanstack/router-devtools

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

@tanstack/router-devtools-core

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

@tanstack/router-generator

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

@tanstack/router-plugin

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

@tanstack/router-ssr-query-core

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

@tanstack/router-utils

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

@tanstack/router-vite-plugin

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

@tanstack/solid-router

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

@tanstack/solid-router-devtools

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

@tanstack/solid-router-ssr-query

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

@tanstack/solid-start

npm i https://pkg.pr.new/@tanstack/solid-start@8354

@tanstack/solid-start-client

npm i https://pkg.pr.new/@tanstack/solid-start-client@8354

@tanstack/solid-start-server

npm i https://pkg.pr.new/@tanstack/solid-start-server@8354

@tanstack/start-client-core

npm i https://pkg.pr.new/@tanstack/start-client-core@8354

@tanstack/start-fn-stubs

npm i https://pkg.pr.new/@tanstack/start-fn-stubs@8354

@tanstack/start-plugin-core

npm i https://pkg.pr.new/@tanstack/start-plugin-core@8354

@tanstack/start-server-core

npm i https://pkg.pr.new/@tanstack/start-server-core@8354

@tanstack/start-static-server-functions

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

@tanstack/start-storage-context

npm i https://pkg.pr.new/@tanstack/start-storage-context@8354

@tanstack/valibot-adapter

npm i https://pkg.pr.new/@tanstack/valibot-adapter@8354

@tanstack/virtual-file-routes

npm i https://pkg.pr.new/@tanstack/virtual-file-routes@8354

@tanstack/vue-router

npm i https://pkg.pr.new/@tanstack/vue-router@8354

@tanstack/vue-router-devtools

npm i https://pkg.pr.new/@tanstack/vue-router-devtools@8354

@tanstack/vue-router-ssr-query

npm i https://pkg.pr.new/@tanstack/vue-router-ssr-query@8354

@tanstack/vue-start

npm i https://pkg.pr.new/@tanstack/vue-start@8354

@tanstack/vue-start-client

npm i https://pkg.pr.new/@tanstack/vue-start-client@8354

@tanstack/vue-start-server

npm i https://pkg.pr.new/@tanstack/vue-start-server@8354

@tanstack/zod-adapter

npm i https://pkg.pr.new/@tanstack/zod-adapter@8354

commit: 7649ecf

@nx-cloud nx-cloud Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Important

At least one additional CI pipeline execution has run since the conclusion below was written and it may no longer be applicable.

Nx Cloud has identified a possible root cause for your failed CI:

We classified this failure as an environment state issue rather than a code change. The error originates in a stale build artifact (e2e/e2e-utils/dist/esm/index.js) of a package untouched by this PR, and the same failure does not appear on main. Rebuilding the CI environment's dist artifacts should resolve it.

No code changes were suggested for this issue.

Trigger a rerun:

Rerun CI

Nx Cloud View detailed reasoning on Nx Cloud ↗


🎓 Learn more about Self-Healing CI on nx.dev

@codspeed

codspeed Bot commented Sep 11, 2026

Copy link
Copy Markdown

Merging this PR will improve performance by 6.27%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 10 improved benchmarks
✅ 170 untouched benchmarks

Performance Changes

Mode Benchmark BASE HEAD Efficiency
⚡ Simulation ssr server-route (vue) 155.2 ms 141.3 ms +9.8%
⚡ Simulation ssr global-mw server-route (solid) 205 ms 188.4 ms +8.85%
⚡ Simulation ssr global-mw server-route (react) 210.2 ms 193.8 ms +8.42%
⚡ Simulation ssr global-mw server-route (vue) 208.5 ms 193.5 ms +7.75%
⚡ Simulation ssr not-found (solid) 179 ms 169.2 ms +5.75%
⚡ Simulation ssr server-route middleware (vue) 162.6 ms 155.1 ms +4.83%
⚡ Simulation ssr server-route middleware (solid) 160.4 ms 153.2 ms +4.7%
⚡ Simulation ssr server-route middleware (react) 163.7 ms 156.4 ms +4.67%
⚡ Simulation ssr server-route (solid) 144.6 ms 138.7 ms +4.23%
⚡ Simulation ssr server-route (react) 148.7 ms 143.1 ms +3.92%

Tip

Curious why performance improved? Comment @codspeedbot explain why performance improved on this PR, or directly use the CodSpeed MCP with your agent.


Comparing codex/server-history (7649ecf) with main (6494e75)

Open in CodSpeed

@Sheraff
Sheraff merged commit 9872d2a into main Sep 11, 2026
28 of 29 checks passed
@Sheraff
Sheraff deleted the codex/server-history branch September 11, 2026 09:45
@github-actions github-actions Bot mentioned this pull request Sep 11, 2026
sixthshift added a commit to sixthshift/garnish that referenced this pull request Sep 18, 2026
…cript 7

@sixthshift/design-system 0.4.0 → 0.5.0, @tanstack/react-router 1.170.36,
@tanstack/react-start 1.168.54, @tanstack/start-storage-context 1.167.32,
vite 8.3.0, zod 4.6.5, typescript 7.0.2 (the native compiler; tsc --noEmit
passes and still catches a planted error).

Router-core 1.171.30 (TanStack/router#8354) makes router.navigate a no-op
when the router believes it is on the server, which under vitest it is. The
client-scale test simulated pressing plus with navigate; it now writes the
built href to the history and loads, which is what navigate does in a
browser. The lockfile was regenerated from scratch while chasing that, so
its diff is larger than the bumps alone.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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.

1 participant