Skip to content

fix(pages): commit the destination URL when navigating with preserveState - #531

Merged
Brooooooklyn merged 2 commits into
voidzero-dev:mainfrom
0froq:fix/preserve-state-url
Oct 22, 2026
Merged

Brooooooklyn merged 2 commits into
voidzero-dev:mainfrom
0froq:fix/preserve-state-url

Conversation

@0froq

@0froq 0froq commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #506

Summary

router.visit(url, { preserveState: true }) updated the page but skipped the history write, so the address bar kept the old URL. makeCommit() in packages/void/src/pages/navigation-engine.ts gated the history write on !options.preserveState; it now gates on !options._popstate.

  • Every normal visit writes history; only back/forward traversal (_popstate) skips it.
  • preserveState now only affects component state; replace still chooses replaceState vs pushState.
  • router.refresh() defaults to replace: true, so it updates the current entry instead of pushing a new one.

#507 is a separate bug and is not addressed here.

Tests

Added 4 cases to packages/void/test/unit/pages-client.test.ts:

  • preserveState + push writes the destination URL with pushState
  • preserveState + replace writes it with replaceState
  • refresh() does not push a new history entry
  • popstate navigation does not write history

The push/replace cases fail on main and pass with this change. vp test run test/unit/pages-client.test.ts passes (53/53); typecheck, fmt and lint pass.

Follow-up changes (085e16b)

  • router.refresh() now goes through one shared refreshPage() helper, used by both the core router and React's own router. React's copy was missed and would have pushed a new entry.
  • refresh() keeps the URL hash. Replacing the entry with pathname + search dropped #hash. An internal _refresh flag makes sure the page is still fetched and not treated as a hash-only visit.
  • Same-page hash visits (visit('#x', { preserveState: true })) now write history too, by the same rule. The fix: Hash navigation should not make requests + should not reset fonts/css. #130 test that asserted otherwise is updated.
  • A replaced history entry keeps its scroll key, so repeated refresh() calls (e.g. polling) don't add one saved position per call to sessionStorage.
  • Docs: the router.refresh() example notes it keeps the same history entry.

0froq and others added 2 commits October 21, 2026 17:25
…tate

preserveState now only controls component state preservation. Normal
visits always write history (push, or replace with replace: true);
back/forward traversal still skips history writes and router.refresh()
replaces the current entry instead of adding one.

Fixes voidzero-dev#506
- router.refresh() goes through one shared helper used by the core and
  React routers. React's copy still pushed a new history entry.
- refresh() keeps the URL hash; it now replaces the entry, which dropped
  it. An internal _refresh flag stops it from being taken as a hash-only
  visit, so the page is still fetched.
- Same-page hash visits write history with preserveState too, like other
  visits.
- A replaced history entry keeps its scroll key, so repeated refreshes
  no longer add a saved position each time.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@Brooooooklyn

Copy link
Copy Markdown
Member

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 21, 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-10-21T12:56:45.351167Z 085e16b Manual request
ℹ️ 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.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Already looking forward to the next diff.

Reviewed commit: 085e16b365

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

@Brooooooklyn
Brooooooklyn merged commit dc0c3c1 into voidzero-dev:main Oct 22, 2026
18 checks passed
@0froq

0froq commented Oct 22, 2026

Copy link
Copy Markdown
Contributor Author

Thank you!!!

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.

Pages: preserveState prevents the destination URL from being committed

2 participants