Repository navigation
Ignore anchor clicks whose default action is prevented - #803
Merged
opqdonut merged 3 commits intoOct 7, 2026
Merged
Conversation
Html5History checks modifier keys, the mouse button, the target attribute and contenteditable before it takes over a link click, but it does not look at defaultPrevented. A listener closer to the anchor that cancels the navigation is therefore ignored, and the router still pushes a new history entry. This makes it impossible to have a link that opens something else when clicked while keeping its href for focus order and "open in new tab". Dropping the href is not an option: the anchor then stops being focusable. Preventing the default action means the browser would not navigate either, so neither should the router. React Router and Vue Router both skip the click in this case, and with the Navigation API the navigate event is not fired at all.
chaploud
force-pushed
the
ignore-default-prevented-anchor-clicks
branch
from
September 23, 2026 12:49
90675cd to
b28f847
Compare
chaploud
marked this pull request as ready for review
September 23, 2026 12:50
opqdonut
reviewed
Sep 29, 2026
| * Better support for `:and`, `:or`, `:union` and `:merge` when generating OpenAPI. [#791](https://github.com/metosin/reitit/pull/791) | ||
| * Doc improvements | ||
| * Improve OpenAPI output for Schema `s/Any` type: it now maps to JSON Schema `{}` in request and response bodies. [#801](https://github.com/metosin/reitit/pull/801) | ||
| * **reitit-frontend**: `Html5History` no longer handles anchor clicks whose default action has already been prevented. [#803](https://github.com/metosin/reitit/pull/803) |
Member
There was a problem hiding this comment.
now that 0.11.0 is out, this changelog line will land in the wrong place. please merge/rebase master
Member
|
I need the opinion of someone with more frontend knowledge than me to be able to merge this. Can some existing usecases / workarounds for this break? |
Member
|
The one line change to the click handling condition does make sense. Test case looks ok. Interestingly, I did look at the React-router logic back in 2019 when this was added (#256) but for some reason I didn't add it then, though it seems react-router checked the defaultPrevented back then. Perhaps I looked at the other cljs routing libs more and they didn't check this. Anyway, LGTM. |
Deraen
approved these changes
Sep 29, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Html5Historytakes over an anchor click after checking modifier keys, the mouse button, thetargetattribute andcontenteditable, but it does not look atdefaultPrevented. A listener closer to the anchor that cancels the navigation is ignored and the router still pushes a history entry.preventDefaultlistener and asserts the location does not change. It fails without the fix.Why this matters
Without it, a link that should open something else when clicked cannot keep its
href:The sheet opens and the router navigates away at the same time. Dropping the
hrefworks around it, but the anchor then stops being focusable, so keyboard users skip it and "open in new tab" disappears from the context menu. The same applies to a navigation item that cancels a click on the entry for the current page: today every click grows the history stack.Prior art
React Router and Vue Router both skip the click when
defaultPreventedis set. With the Navigation API thenavigateevent is not fired at all for a click whose default action was prevented, so the platform encodes the same rule.Notes
document, so listeners on the anchor run first anddefaultPreventedis already set when the predicate runs.goog.events.BrowserEventcopies the flag from the native event when it wraps it, so this also covers handlers that call the nativepreventDefault, such as React's../scripts/test.sh cljspasses (73 tests, node-test and both karma runs).