Skip to content

Improve browser navigation interactions#3

Merged
ahjephson merged 5 commits into
developfrom
feature/navigation-improvements
May 6, 2026
Merged

Improve browser navigation interactions#3
ahjephson merged 5 commits into
developfrom
feature/navigation-improvements

Conversation

@ahjephson
Copy link
Copy Markdown
Contributor

Improve browser navigation Blazor hooks to prevent quick navigations from being ignored by Blazor.

Copy link
Copy Markdown

@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: 8e39b0ed80

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

Comment thread src/Blazor.HashRouting/wwwroot/hash-routing.module.js
@chatgpt-codex-connector
Copy link
Copy Markdown

💡 Codex Review

if (!canRevertWithHistory && hashRoutingState.lastAcceptedHashAbsoluteUri) {
const rollbackState = withHistoryMetadata(window.history.state, hashRoutingState.lastAcceptedHistoryState, hashRoutingState.currentHistoryIndex);
window.history.replaceState(rollbackState, "", hashRoutingState.lastAcceptedHashAbsoluteUri);

P1 Badge Restore rejected URL when history-based revert does not run

When navigationLockEnabled is true and history.go(-historyDelta) is throttled/ignored/throws, navigateHistoryWithoutBrowserNavigationEvents(...) returns false, but the denial path only checks !canRevertWithHistory before rolling back. In that case canRevertWithHistory is still true, so a rejected back/forward navigation can leave window.location on the denied URL instead of restoring lastAcceptedHashAbsoluteUri, which breaks the navigation lock contract for users on browsers that suppress history.go calls.


function completeSuppressedBrowserNavigationEvent(navigationKey) {
const resolverEntry = hashRoutingState.suppressedBrowserNavigationEventResolvers.shift();
if (!resolverEntry) {

P2 Badge Match suppressed resolver to the expected navigation event

completeSuppressedBrowserNavigationEvent consumes the oldest resolver with shift() before validating which navigation actually fired, so any browser navigation event can satisfy suppression. If the internal history.go call is ignored and the user triggers a different navigation within the timeout window, that real navigation is dropped and never processed by Blazor. Fresh evidence is that this function unconditionally resolves the queued entry regardless of navigationKey.

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

@chatgpt-codex-connector
Copy link
Copy Markdown

💡 Codex Review

if (revertedWithHistory) {
await navigateHistoryWithoutBrowserNavigationEvents(historyDelta, browserNavigation.navigationKey);

P1 Badge Check re-apply history.go result before replacing state

After a successful temporary revert, the code re-applies the user navigation with navigateHistoryWithoutBrowserNavigationEvents(historyDelta, ...) but ignores its boolean result. If that second history.go is throttled/ignored/throws, the browser stays on the reverted entry, and the subsequent replaceState rewrites that wrong entry to the target URL/index, which can corrupt back/forward history and desynchronize _qhrIndex from the actual stack position.

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

Copy link
Copy Markdown

@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: 2a20c8d3ea

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

Comment on lines +487 to +490
resolverEntry.timeoutId = setTimeout(function () {
removeSuppressedBrowserNavigationEventResolver(resolverEntry);
resolve(false);
}, suppressedBrowserNavigationTimeoutMilliseconds);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Avoid hard-failing suppressed history waits after 100ms

The suppression wait currently times out after a fixed 100ms, which is short enough that legitimate popstate/hashchange events can arrive late on throttled or busy browsers. In that case the resolver is removed and navigation is treated as a failed revert/reapply, and when the delayed browser event finally arrives it is no longer suppressed and can be processed as a separate navigation. This can cause missed or out-of-order NotifyLocationChangedFromJs behavior during locked back/forward navigation under load.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@ahjephson ahjephson merged commit 22c9a97 into develop May 6, 2026
2 checks passed
@ahjephson ahjephson deleted the feature/navigation-improvements branch May 6, 2026 20:41
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.

1 participant