Skip to content

fix(router-core): allow retained search params to reset to defaults - #7559

Merged
schiller-manuel merged 2 commits into
mainfrom
fix-7558
Jun 6, 2026
Merged

fix(router-core): allow retained search params to reset to defaults#7559
schiller-manuel merged 2 commits into
mainfrom
fix-7558

Conversation

@schiller-manuel

@schiller-manuelschiller-manuel commented Jun 6, 2026

Copy link
Copy Markdown
Collaborator

fixes#7558

Summary by CodeRabbit

  • Bug Fixes

    • Fixed an issue where retained search params could incorrectly override navigations that explicitly specify default-valued search parameters when using stripSearchParams.
  • Tests

    • Added test cases to verify search parameter retention behavior with search param stripping.

@coderabbitai

coderabbitaiBot commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

Ready to act? Review this PR in Change Stack to turn feedback into patch suggestions you can inspect and refine.

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4af3c113-b878-46ea-ab67-fcfd0b057f86

📥 Commits

Reviewing files that changed from the base of the PR and between e99e855 and 869fab1.

📒 Files selected for processing (6)
  • .changeset/fix-retain-strip-explicit-defaults.md
  • packages/router-core/src/route.ts
  • packages/router-core/src/router.ts
  • packages/router-core/src/searchMiddleware.ts
  • packages/router-core/src/utils.ts
  • packages/router-core/tests/build-location.test.ts

📝 Walkthrough

Walkthrough

Router search middleware now tracks explicitly-provided navigation search input via a new meta.explicit field, allowing retainSearchParams and stripSearchParams to properly handle scenarios where a user explicitly navigates to default-valued parameters that would otherwise be stripped.

Changes

Search explicit tracking and retain/strip behavior

Layer / File(s)Summary
Search metadata contract and explicit tracking infrastructure
packages/router-core/src/route.ts, packages/router-core/src/utils.ts, packages/router-core/src/router.ts
SearchMiddlewareMeta adds an optional explicit field. hasOwn is exported from utils. Router middleware stores the computed explicit search value into meta.explicit during functional updates.
Retain/strip behavior with explicit-default awareness and validation
packages/router-core/src/searchMiddleware.ts, packages/router-core/tests/build-location.test.ts, .changeset/fix-retain-strip-explicit-defaults.md
retainSearchParams imports hasOwn and refactors removal/retention logic across three key branches to consult meta.explicit alongside meta.removed and meta.removedAny, preventing retained params from blocking explicit navigation to defaults. Two new test cases verify the fix for both keyed and whole-retention modes, and a changeset documents the patch-level fix.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • TanStack/router#7555: Both PRs modify packages/router-core/src/searchMiddleware.ts to prevent retainSearchParams from reintroducing search keys that stripSearchParams should remove, using explicit metadata to coordinate the two functions.
  • TanStack/router#7557: Both PRs add regression test cases to packages/router-core/tests/build-location.test.ts for retainSearchParams behavior under search param changes.
  • TanStack/router#7549: Both PRs modify packages/router-core/src/searchMiddleware.ts and router metadata plumbing to fix retainSearchParams handling of default values, though using different metadata mechanisms.

Suggested reviewers

  • chorobin

Poem

🐰 A rabbit hops through search param seas,
Where strips and retains dance with ease—
Explicit defaults now shine so clear,
No more lost params, the fix is here!
Defaults restored, the path is bright.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 50.00% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly and concisely describes the main fix: allowing retained search params to reset to default values, which directly addresses the linked issue #7558.
Linked Issues check✅ PassedThe PR implements the required fix for issue #7558 by tracking explicit search param values and using them in retainSearchParams to allow params to reset to defaults when used with stripSearchParams.
Out of Scope Changes check✅ PassedAll code changes are directly related to fixing the retainSearchParams and stripSearchParams interaction issue; no unrelated modifications are present.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-7558

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

@nx-cloud

nx-cloudBot commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

View your CI Pipeline Execution ↗ for commit b073a1d

CommandStatusDurationResult
nx affected --targets=test:eslint,test:unit,tes...✅ Succeeded10m 28sView ↗
nx run-many --target=build --exclude=examples/*...✅ Succeeded2m 12sView ↗

💡 Verify your cache is correct by running tasks in a sandbox. Read docs ↗


☁️ Nx Cloud last updated this comment at 2026-06-06 08:25:30 UTC

@schiller-manuelschiller-manuel changed the title add regression testsfix(router-core): allow retained search params to reset to defaultsJun 6, 2026
@github-actions

github-actionsBot commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

🚀 Changeset Version Preview

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

🟩 Patch bumps

PackageVersionReason
@tanstack/router-core1.171.11 → 1.171.12Changeset
@tanstack/react-router1.170.13 → 1.170.14Dependent
@tanstack/react-start1.168.22 → 1.168.23Dependent
@tanstack/react-start-client1.168.10 → 1.168.11Dependent
@tanstack/react-start-rsc0.1.21 → 0.1.22Dependent
@tanstack/react-start-server1.167.16 → 1.167.17Dependent
@tanstack/router-cli1.167.15 → 1.167.16Dependent
@tanstack/router-generator1.167.15 → 1.167.16Dependent
@tanstack/router-plugin1.168.16 → 1.168.17Dependent
@tanstack/router-vite-plugin1.167.16 → 1.167.17Dependent
@tanstack/solid-router1.170.13 → 1.170.14Dependent
@tanstack/solid-start1.168.22 → 1.168.23Dependent
@tanstack/solid-start-client1.168.10 → 1.168.11Dependent
@tanstack/solid-start-server1.167.16 → 1.167.17Dependent
@tanstack/start-client-core1.170.9 → 1.170.10Dependent
@tanstack/start-plugin-core1.171.14 → 1.171.15Dependent
@tanstack/start-server-core1.169.11 → 1.169.12Dependent
@tanstack/start-static-server-functions1.167.14 → 1.167.15Dependent
@tanstack/start-storage-context1.167.13 → 1.167.14Dependent
@tanstack/vue-router1.170.13 → 1.170.14Dependent
@tanstack/vue-start1.168.21 → 1.168.22Dependent
@tanstack/vue-start-client1.167.14 → 1.167.15Dependent
@tanstack/vue-start-server1.167.16 → 1.167.17Dependent

@github-actions

Copy link
Copy Markdown
Contributor

Bundle Size Benchmarks

  • Commit: 5943d950ffd7
  • Measured at: 2026-06-06T08:15:52.278Z
  • Baseline source: history:e99e855258e3
  • Dashboard: bundle-size history
ScenarioCurrent (gzip)Delta vs baselineInitial gzipRawBrotliTrend
react-router.minimal87.26 KiB+18 B (+0.02%)87.12 KiB273.77 KiB75.89 KiB▇▁▁▁▁▁▁▁▆▆▆█
react-router.full91.09 KiB+71 B (+0.08%)90.95 KiB286.16 KiB79.16 KiB▂▁▁▁▁▁▁▁▇▇▇█
solid-router.minimal35.48 KiB+16 B (+0.04%)35.36 KiB106.07 KiB31.97 KiB▇▁▁▁▁▁▁▁▆▆▆█
solid-router.full40.55 KiB+42 B (+0.10%)40.42 KiB121.29 KiB36.43 KiB▂▁▁▁▁▁▁▁▇▇▇█
vue-router.minimal52.97 KiB+24 B (+0.04%)52.84 KiB150.09 KiB47.65 KiB█▁▁▁▁▁▁▁▅▅▅█
vue-router.full58.96 KiB+31 B (+0.05%)58.83 KiB168.84 KiB52.81 KiB▂▁▁▁▁▁▁▁▇▇▇█
react-start.minimal101.88 KiB+19 B (+0.02%)101.74 KiB322.09 KiB88.14 KiB█▁▁▁▁▁▁▁▆▆▆█
react-start.deferred-hydration102.62 KiB+17 B (+0.02%)101.76 KiB323.46 KiB88.90 KiB▇▁▁▁▁▁▁▁▆▆▆█
react-start.full105.29 KiB+43 B (+0.04%)105.15 KiB332.40 KiB90.98 KiB▅▁▁▁▁▁▁▁▄▄▄█
react-start.rsbuild.minimal99.59 KiB+21 B (+0.02%)99.42 KiB316.58 KiB85.76 KiB▇▁▁▁▁▁▁▁▅▅▅█
react-start.rsbuild.minimal-iife99.99 KiB+20 B (+0.02%)99.82 KiB317.51 KiB86.04 KiB▇▁▁▁▁▁▁▁▅▅▅█
react-start.rsbuild.full102.85 KiB+20 B (+0.02%)102.68 KiB326.97 KiB88.40 KiB█▁▁▁▁▁▁▁▅▅▅█
solid-start.minimal49.60 KiB+21 B (+0.04%)49.46 KiB152.14 KiB43.77 KiB▆▁▁▁▁▁▁▁▅▅▅█
solid-start.deferred-hydration52.86 KiB+20 B (+0.04%)49.52 KiB160.18 KiB46.76 KiB▆▁▁▁▁▁▁▁▅▅▅█
solid-start.full55.38 KiB+19 B (+0.03%)55.25 KiB169.07 KiB48.83 KiB▇▁▁▁▁▁▁▁▅▅▅█
vue-start.minimal71.02 KiB+23 B (+0.03%)70.89 KiB207.23 KiB62.85 KiB▇▁▁▁▁▁▁▁▅▅▅█
vue-start.full74.98 KiB+22 B (+0.03%)74.85 KiB219.75 KiB66.30 KiB▇▁▁▁▁▁▁▁▅▅▅█

Current gzip tracks all emitted client JS chunks. Initial gzip tracks only the entry/import graph. Trend sparkline is historical current gzip ending with this PR measurement; lower is better.

@pkg-pr-new

pkg-pr-newBot commented Jun 6, 2026

Copy link
Copy Markdown
More templates

@tanstack/arktype-adapter

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

@tanstack/eslint-plugin-router

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

@tanstack/eslint-plugin-start

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

@tanstack/history

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

@tanstack/nitro-v2-vite-plugin

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

@tanstack/react-router

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

@tanstack/react-router-devtools

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

@tanstack/react-router-ssr-query

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

@tanstack/react-start

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

@tanstack/react-start-client

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

@tanstack/react-start-rsc

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

@tanstack/react-start-server

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

@tanstack/router-cli

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

@tanstack/router-core

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

@tanstack/router-devtools

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

@tanstack/router-devtools-core

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

@tanstack/router-generator

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

@tanstack/router-plugin

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

@tanstack/router-ssr-query-core

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

@tanstack/router-utils

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

@tanstack/router-vite-plugin

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

@tanstack/solid-router

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

@tanstack/solid-router-devtools

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

@tanstack/solid-router-ssr-query

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

@tanstack/solid-start

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

@tanstack/solid-start-client

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

@tanstack/solid-start-server

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

@tanstack/start-client-core

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

@tanstack/start-fn-stubs

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

@tanstack/start-plugin-core

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

@tanstack/start-server-core

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

@tanstack/start-static-server-functions

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

@tanstack/start-storage-context

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

@tanstack/valibot-adapter

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

@tanstack/virtual-file-routes

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

@tanstack/vue-router

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

@tanstack/vue-router-devtools

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

@tanstack/vue-router-ssr-query

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

@tanstack/vue-start

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

@tanstack/vue-start-client

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

@tanstack/vue-start-server

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

@tanstack/zod-adapter

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

commit: 869fab1

@codspeed-hq

codspeed-hqBot commented Jun 6, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 4 untouched benchmarks
⏩ 2 skipped benchmarks1


Comparing fix-7558 (869fab1) with main (e99e855)

Open in CodSpeed

Footnotes

  1. 2 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@schiller-manuel
schiller-manuel merged commit df1076c into mainJun 6, 2026
20 checks passed
@schiller-manuel
schiller-manuel deleted the fix-7558 branch June 6, 2026 08:30
@github-actionsgithub-actionsBot mentioned this pull request Jun 6, 2026
Sign up for freeto 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.

retainSearchParams prevents params from being set back to default values when used with stripSearchParams

1 participant

@schiller-manuel