Skip to content

fix: preserve navigation state in setSearchParams and add replace option#225

Merged
uhyo merged 2 commits into
masterfrom
claude/issue-208-ytsz30
Jul 12, 2026
Merged

fix: preserve navigation state in setSearchParams and add replace option#225
uhyo merged 2 commits into
masterfrom
claude/issue-208-ytsz30

Conversation

@uhyo

@uhyo uhyo commented Jul 12, 2026

Copy link
Copy Markdown
Owner

Closes #208

Bug fix

setSearchParams performed a replace navigation without passing state, so the new entry's state — including the internal __routeStates written by setState/setStateSync — was silently wiped whenever a query param changed. The setter now reads the current entry's state from RouterContext and passes it through on replace navigations.

New option

The setter accepts an optional second argument:

setSearchParams(params, { replace?: boolean }); // replace defaults to true
  • replace: true (default): replaces the current entry and preserves its navigation state — previous behavior, minus the state loss.
  • replace: false: pushes a new entry so the change can be backed out of with the browser's Back button. The new entry starts without state, consistent with every other push navigation.

The SetSearchParamsOptions type is exported from the package entry point.

The state option suggested in the issue was deliberately left out: the entry state is an internal container for per-route state and there is no public API to read raw entry state back, so exposing it would only let callers clobber route state.

Tests & docs

  • Added tests for state preservation on replace (end-to-end through setStateSync) and for pushing via replace: false.
  • Updated the useSearchParams docs (ApiHooksPage) and added SetSearchParamsOptions to the types reference.

🤖 Generated with Claude Code

https://claude.ai/code/session_01XyJBmbRYRVoU5WLYxUs8N6


Generated by Claude Code

claude added 2 commits July 12, 2026 02:56
setSearchParams performed a replace navigation without passing state,
wiping per-route state stored on the current entry (via setState /
setStateSync). It now preserves the current entry's state on replace
navigations by default.

It also accepts a new second argument:
setSearchParams(params, { replace?: boolean; state?: unknown }).
replace defaults to true (previous behavior); replace: false pushes a
new entry so the change can be backed out of, and an explicit state
option takes precedence in both cases.

Closes #208

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XyJBmbRYRVoU5WLYxUs8N6
The entry state is an internal container for per-route state, and there
is no public API to read raw entry state back, so exposing a raw state
option would only let callers clobber route state. Keep the replace
option and the state-preservation behavior.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XyJBmbRYRVoU5WLYxUs8N6
@uhyo
uhyo merged commit 5d3d8e7 into master Jul 12, 2026
1 check passed
@uhyo
uhyo deleted the claude/issue-208-ytsz30 branch July 12, 2026 03:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

setSearchParams wipes navigation state; no push/state options

2 participants