Skip to content

refactor(router-core): restore 'url' field on ParsedLocation#6939

Draft
Sheraff wants to merge 4 commits intomainfrom
refactor-router-core-parsed-location-url
Draft

refactor(router-core): restore 'url' field on ParsedLocation#6939
Sheraff wants to merge 4 commits intomainfrom
refactor-router-core-parsed-location-url

Conversation

@Sheraff
Copy link
Contributor

@Sheraff Sheraff commented Mar 16, 2026

back by popular demand

Summary by CodeRabbit

  • New Features

    • ParsedLocation objects now include a read-only URL representation via a new url property (exposed as a computed, memoized getter).
  • Documentation

    • API docs updated: url is computed on demand; repeatedly accessing it in tight/hot loops may impact performance.

@changeset-bot
Copy link

changeset-bot bot commented Mar 16, 2026

🦋 Changeset detected

Latest commit: 7b3861b

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 27 packages
Name Type
@tanstack/router-core Minor
@tanstack/react-router-devtools Major
@tanstack/react-router Patch
@tanstack/react-start-client Patch
@tanstack/react-start-server Patch
@tanstack/router-devtools-core Major
@tanstack/router-generator Patch
@tanstack/router-plugin Patch
@tanstack/solid-router-devtools Major
@tanstack/solid-router Patch
@tanstack/solid-start-client Patch
@tanstack/solid-start-server Patch
@tanstack/start-client-core Patch
@tanstack/start-plugin-core Patch
@tanstack/start-server-core Patch
@tanstack/start-storage-context Patch
@tanstack/vue-router-devtools Major
@tanstack/vue-router Patch
@tanstack/vue-start-client Patch
@tanstack/vue-start-server Patch
@tanstack/router-devtools Patch
@tanstack/react-start Patch
@tanstack/router-cli Patch
@tanstack/router-vite-plugin Patch
@tanstack/solid-start Patch
@tanstack/start-static-server-functions Patch
@tanstack/vue-start Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions github-actions bot added documentation Everything documentation related package: router-core labels Mar 16, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 16, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c8d416e8-3846-4f6e-aa6a-e4ea3b22a449

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a memoized, non-enumerable url getter to ParsedLocation, updates the interface and docs, and augments router code paths to attach the URL getter to parsed/build locations across rewrite and fast-path flows.

Changes

Cohort / File(s) Summary
Release & Documentation
/.changeset/five-otters-feel.md, docs/router/api/router/ParsedLocationType.md
Adds changeset for a minor release and documents the new url: URL getter on ParsedLocation, noting it is computed on demand and may be expensive in hot loops.
Core Implementation
packages/router-core/src/location.ts, packages/router-core/src/router.ts
Adds url: URL to ParsedLocation and implements augmentLocationWithUrl in router.ts. Augments parsed/build location objects (rewrite and fast paths) with a lazy, memoized, non-enumerable url getter, threading origin and memoization through relevant flows.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A tiny URL hops into view,
Nestled in ParsedLocation, new and true.
Lazy and clever, it waits to be found,
Memoized, quiet, not making a sound.
Hop on—this rabbit’s code is through!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: restoring the 'url' field on ParsedLocation, which aligns with the changeset, documentation update, and implementation across multiple files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor-router-core-parsed-location-url
📝 Coding Plan
  • Generate coding plan for human review comments

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

@nx-cloud
Copy link

nx-cloud bot commented Mar 16, 2026

View your CI Pipeline Execution ↗ for commit 447c9f8

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

☁️ Nx Cloud last updated this comment at 2026-03-16 20:21:21 UTC

@github-actions
Copy link
Contributor

github-actions bot commented Mar 16, 2026

Changeset Version Preview

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

Direct bumps

Package Bump Version
@tanstack/router-core minor 1.167.3 → 1.168.0
Dependency bumps (21)
Package Bump Version
@tanstack/react-router patch 1.167.3 → 1.167.4
@tanstack/react-start patch 1.166.14 → 1.166.15
@tanstack/react-start-client patch 1.166.12 → 1.166.13
@tanstack/react-start-server patch 1.166.12 → 1.166.13
@tanstack/router-cli patch 1.166.11 → 1.166.12
@tanstack/router-generator patch 1.166.11 → 1.166.12
@tanstack/router-plugin patch 1.166.12 → 1.166.13
@tanstack/router-vite-plugin patch 1.166.12 → 1.166.13
@tanstack/solid-router patch 1.167.3 → 1.167.4
@tanstack/solid-start patch 1.166.14 → 1.166.15
@tanstack/solid-start-client patch 1.166.11 → 1.166.12
@tanstack/solid-start-server patch 1.166.11 → 1.166.12
@tanstack/start-client-core patch 1.166.11 → 1.166.12
@tanstack/start-plugin-core patch 1.166.14 → 1.166.15
@tanstack/start-server-core patch 1.166.11 → 1.166.12
@tanstack/start-static-server-functions patch 1.166.13 → 1.166.14
@tanstack/start-storage-context patch 1.166.11 → 1.166.12
@tanstack/vue-router patch 1.167.3 → 1.167.4
@tanstack/vue-start patch 1.166.14 → 1.166.15
@tanstack/vue-start-client patch 1.166.11 → 1.166.12
@tanstack/vue-start-server patch 1.166.11 → 1.166.12

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 26f6655750

ℹ️ 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".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@github-actions
Copy link
Contributor

github-actions bot commented Mar 16, 2026

Bundle Size Benchmarks

  • Commit: 8afd52b12bcc
  • Measured at: 2026-03-16T20:10:49.008Z
  • Baseline source: history:32fcba7b044b
  • Dashboard: bundle-size history
Scenario Current (gzip) Delta vs baseline Raw Brotli Trend
react-router.minimal 87.69 KiB +81 B (+0.09%) 276.26 KiB 76.10 KiB ▁▁▁▁▁▁▁▁▁▇▇█
react-router.full 90.72 KiB +74 B (+0.08%) 286.48 KiB 78.83 KiB ▁▁▁▁▁▁▁▁▁▇▇█
solid-router.minimal 37.20 KiB +70 B (+0.18%) 111.55 KiB 33.40 KiB ▁▁▁▁▁▁▁▁▁▇▇█
solid-router.full 41.44 KiB +82 B (+0.19%) 124.36 KiB 37.13 KiB ▁▁▁▁▁▁▁▁▁▇▇█
vue-router.minimal 53.06 KiB +72 B (+0.13%) 151.59 KiB 47.74 KiB ▁▁▁▁▁▁▁▁▁▇▇█
vue-router.full 57.76 KiB +72 B (+0.12%) 166.52 KiB 51.73 KiB ▁▁▁▁▁▁▁▁▁▇▇█
react-start.minimal 102.06 KiB +73 B (+0.07%) 324.27 KiB 88.28 KiB ▁▁▁▁▁▁▁▁▁███
react-start.full 105.41 KiB +72 B (+0.07%) 334.08 KiB 91.05 KiB ▁▁▁▁▁▁▁▁▁███
solid-start.minimal 51.30 KiB +66 B (+0.13%) 158.00 KiB 45.38 KiB ▁▁▁▁▁▁▁▁▁███
solid-start.full 56.58 KiB +54 B (+0.09%) 173.49 KiB 49.84 KiB ▁▁▁▁▁▁▁▁▁███

Trend sparkline is historical gzip bytes ending with this PR measurement; lower is better.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 16, 2026

More templates

@tanstack/arktype-adapter

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

@tanstack/eslint-plugin-router

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

@tanstack/history

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

@tanstack/nitro-v2-vite-plugin

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

@tanstack/react-router

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

@tanstack/react-router-devtools

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

@tanstack/react-router-ssr-query

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

@tanstack/react-start

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

@tanstack/react-start-client

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

@tanstack/react-start-server

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

@tanstack/router-cli

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

@tanstack/router-core

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

@tanstack/router-devtools

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

@tanstack/router-devtools-core

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

@tanstack/router-generator

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

@tanstack/router-plugin

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

@tanstack/router-ssr-query-core

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

@tanstack/router-utils

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

@tanstack/router-vite-plugin

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

@tanstack/solid-router

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

@tanstack/solid-router-devtools

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

@tanstack/solid-router-ssr-query

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

@tanstack/solid-start

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

@tanstack/solid-start-client

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

@tanstack/solid-start-server

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

@tanstack/start-client-core

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

@tanstack/start-fn-stubs

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

@tanstack/start-plugin-core

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

@tanstack/start-server-core

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

@tanstack/start-static-server-functions

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

@tanstack/start-storage-context

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

@tanstack/valibot-adapter

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

@tanstack/virtual-file-routes

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

@tanstack/vue-router

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

@tanstack/vue-router-devtools

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

@tanstack/vue-router-ssr-query

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

@tanstack/vue-start

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

@tanstack/vue-start-client

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

@tanstack/vue-start-server

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

@tanstack/zod-adapter

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

commit: 447c9f8

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/router-core/src/router.ts (1)

1999-2042: ⚠️ Potential issue | 🟠 Major

Memoize the internal URL, not the output-rewritten one.

Line 2006 stores rewrittenUrl in memoUrl, while Lines 2031-2037 still populate href and pathname from the router-internal location. When an output rewrite changes the URL, buildLocation() ends up returning a ParsedLocation whose url is public while href/pathname are internal, so buildLocation() and parseLocation() no longer agree about what url represents.

🛠️ Suggested fix
-        const url = new URL(fullPath, this.origin)
-        const rewrittenUrl = executeRewriteOutput(this.rewrite, url)
-        memoUrl = rewrittenUrl
-        href = url.href.replace(url.origin, '')
-        origin = rewrittenUrl.origin
+        const internalUrl = new URL(fullPath, this.origin)
+        const rewrittenUrl = executeRewriteOutput(
+          this.rewrite,
+          new URL(internalUrl.href),
+        )
+        memoUrl = internalUrl
+        href = internalUrl.href.replace(internalUrl.origin, '')
+        origin = internalUrl.origin
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/router-core/src/router.ts` around lines 1999 - 2042, The bug is that
memoUrl is set to the output-rewritten URL (rewrittenUrl) causing mismatch
between the internal href/pathname and the exported url; change memoization to
store the internal URL used by the router so buildLocation() and parseLocation()
agree: in the rewrite branch, set memoUrl = url (the URL constructed from
fullPath and this.origin) instead of memoUrl = rewrittenUrl, keep origin =
rewrittenUrl.origin and the existing publicHref/ href/ pathname logic, and
ensure augmentLocationWithUrl is still called with that internal memoUrl so the
ParsedLocation.url reflects the router-internal location while publicHref
reflects the rewritten output.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/router-core/src/router.ts`:
- Around line 1305-1320: The temporary parsed location used for masked
navigations (`__tempLocation` / `parsedTempLocation`) loses the non-enumerable
`url` when it is recreated via object spread (e.g., `{ ...parsedTempLocation,
maskedLocation: location }`), so ensure you restore the `url` there too: instead
of relying on the spread, call augmentLocationWithUrl(parsedTempLocation,
this.origin!) (or after the spread call Object.defineProperty to re-add the
non-enumerable `url`) so masked navigations produce a ParsedLocation with `url`
set; update the same pattern around the other similar return paths (the block
around lines 1337–1353) where `parsedTempLocation` is reconstructed.

---

Outside diff comments:
In `@packages/router-core/src/router.ts`:
- Around line 1999-2042: The bug is that memoUrl is set to the output-rewritten
URL (rewrittenUrl) causing mismatch between the internal href/pathname and the
exported url; change memoization to store the internal URL used by the router so
buildLocation() and parseLocation() agree: in the rewrite branch, set memoUrl =
url (the URL constructed from fullPath and this.origin) instead of memoUrl =
rewrittenUrl, keep origin = rewrittenUrl.origin and the existing publicHref/
href/ pathname logic, and ensure augmentLocationWithUrl is still called with
that internal memoUrl so the ParsedLocation.url reflects the router-internal
location while publicHref reflects the rewritten output.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3bcd65ef-d8b0-4b06-a3e7-3ddd5b9a9c1a

📥 Commits

Reviewing files that changed from the base of the PR and between 8afd52b and 6dd532f.

📒 Files selected for processing (4)
  • .changeset/five-otters-feel.md
  • docs/router/api/router/ParsedLocationType.md
  • packages/router-core/src/location.ts
  • packages/router-core/src/router.ts

@codspeed-hq
Copy link

codspeed-hq bot commented Mar 16, 2026

Merging this PR will not alter performance

✅ 6 untouched benchmarks


Comparing refactor-router-core-parsed-location-url (447c9f8) with main (32fcba7)1

Open in CodSpeed

Footnotes

  1. No successful run was found on main (8afd52b) during the generation of this report, so 32fcba7 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@TanStack TanStack deleted a comment from chatgpt-codex-connector bot Mar 16, 2026
@Sheraff Sheraff marked this pull request as draft March 17, 2026 06:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Everything documentation related package: router-core

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant