Skip to content

fix(web-components): prevent double tab open on Ctrl+click in BaseAnchor#35745

Open
zoherghadyali wants to merge 5 commits intomicrosoft:masterfrom
zoherghadyali:fix/anchor-button-ctrl-click-double-tab
Open

fix(web-components): prevent double tab open on Ctrl+click in BaseAnchor#35745
zoherghadyali wants to merge 5 commits intomicrosoft:masterfrom
zoherghadyali:fix/anchor-button-ctrl-click-double-tab

Conversation

@zoherghadyali
Copy link

Bug

Ctrl+clicking (or Cmd+clicking on Mac) a component that extends BaseAnchor — such as <fluent-link> or <fluent-anchor-button> — opens two tabs instead of one.

Root Cause

BaseAnchor.clickHandler calls handleNavigation(true) which invokes window.open(href, '_blank'), but does not call e.preventDefault(). The proxy <a> element (positioned with position: absolute; inset: 0 over the component) also receives the native Ctrl+click, causing the browser to open a second tab via its built-in modifier-click behavior.

On Ctrl+click, two navigations fire:

Step What happens Result
1 Click lands on the proxy <a href="..."> Browser natively opens tab #1
2 Click bubbles to clickHandler, which calls window.open Programmatically opens tab #2

Fix

Call e.preventDefault() in clickHandler when the modifier key is held (ctrlKey on Windows/Linux, metaKey on Mac), before calling handleNavigation(). This lets the component handle new-tab navigation exclusively and prevents the native duplicate.

Changed File

  • packages/web-components/src/anchor-button/anchor-button.base.ts — added e.preventDefault() guard in clickHandler

Testing

  • Verified in Microsoft Edge (Chromium) that Ctrl+click on <fluent-link> now opens exactly one tab
  • Existing anchor-button.spec.ts Ctrl+click Playwright test should continue to pass (it waits for one new page via context.waitForEvent('page'))

@zoherghadyali zoherghadyali requested a review from a team as a code owner February 12, 2026 00:55
@github-actions
Copy link

github-actions bot commented Feb 12, 2026

📊 Bundle size report

✅ No changes found

@github-actions
Copy link

Pull request demo site: URL

@@ -170,6 +170,9 @@ export class BaseAnchor extends FASTElement {
public clickHandler(e: PointerEvent): boolean {
Copy link

@github-actions github-actions bot Feb 12, 2026

Choose a reason for hiding this comment

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

🕵🏾‍♀️ visual changes to review in the Visual Change Report

vr-tests-web-components/Badge 1 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-web-components/Badge. - Dark Mode.normal.chromium.png 443 Changed
vr-tests-web-components/MenuList 3 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-web-components/MenuList. - Dark Mode.normal.chromium.png 498 Changed
vr-tests-web-components/MenuList. - RTL.2nd selected.chromium.png 17 Changed
vr-tests-web-components/MenuList. - RTL.normal.chromium_1.png 39083 Changed
vr-tests-web-components/RadioGroup 1 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-web-components/RadioGroup. - Dark Mode.2nd selected.chromium_3.png 119 Changed
vr-tests-web-components/TextInput 1 screenshots
Image Name Diff(in Pixels) Image Type
vr-tests-web-components/TextInput. - Dark Mode.normal.chromium_1.png 288 Changed

There were 1 duplicate changes discarded. Check the build logs for more information.

@zoherghadyali
Copy link
Author

Hi @chrisdholt @radium-v @marchbox @davatron5000 — could you please review this fix? It addresses a bug where Ctrl+click (or Cmd+click on Mac) on anchor-based components (<fluent-anchor-button>, <fluent-link>) opens two tabs instead of one. The root cause is that clickHandler calls window.open() without e.preventDefault(), so both the programmatic window.open() and the native Ctrl+click on the proxy <a> element fire. The fix adds e.preventDefault() when opening in a new tab. 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.

1 participant

Comments