From 0aa64e755806ed775c0cc21dc6058d86f568f9e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Durg=C3=A9=20Seerden?= Date: Thu, 23 Oct 2025 13:28:29 +0200 Subject: [PATCH 1/2] Use getAttribute to access the element target --- packages/react-router/src/link.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/react-router/src/link.tsx b/packages/react-router/src/link.tsx index 0c817e6d78..fb63cd36a6 100644 --- a/packages/react-router/src/link.tsx +++ b/packages/react-router/src/link.tsx @@ -243,7 +243,9 @@ export function useLinkProps< // The click handler const handleClick = (e: React.MouseEvent) => { // Check actual element's target attribute as fallback - const elementTarget = (e.currentTarget as HTMLAnchorElement).target + const elementTarget = ( + e.currentTarget as HTMLAnchorElement | SVGAElement + ).getAttribute('target') const effectiveTarget = target !== undefined ? target : elementTarget if ( From 729b19152756e7d1eef6eb98a6f83808aaf726ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Durg=C3=A9=20Seerden?= Date: Sat, 25 Oct 2025 14:25:50 +0200 Subject: [PATCH 2/2] Add e2e test for react-router Link in SVG --- e2e/react-router/basic/src/main.tsx | 18 +++++++++++++++++- e2e/react-router/basic/tests/app.spec.ts | 17 +++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/e2e/react-router/basic/src/main.tsx b/e2e/react-router/basic/src/main.tsx index 8bd8d5afcf..36e5106654 100644 --- a/e2e/react-router/basic/src/main.tsx +++ b/e2e/react-router/basic/src/main.tsx @@ -69,7 +69,23 @@ function RootComponent() { }} > This Route Does Not Exist - + {' '} +
+ + Link in SVG + + + + +
diff --git a/e2e/react-router/basic/tests/app.spec.ts b/e2e/react-router/basic/tests/app.spec.ts index 5ccdafa513..ec0e24d8a4 100644 --- a/e2e/react-router/basic/tests/app.spec.ts +++ b/e2e/react-router/basic/tests/app.spec.ts @@ -1,4 +1,8 @@ import { expect, test } from '@playwright/test' +import { getTestServerPort } from '@tanstack/router-e2e-utils' +import packageJson from '../package.json' with { type: 'json' } + +const PORT = await getTestServerPort(packageJson.name) test.beforeEach(async ({ page }) => { await page.goto('/') @@ -45,3 +49,16 @@ test('Navigating to a post page with viewTransition types', async ({ await page.getByRole('link', { name: 'sunt aut facere repe' }).click() await expect(page.getByRole('heading')).toContainText('sunt aut facere') }) + +test('Link in SVG does not trigger a full page reload', async ({ page }) => { + let fullPageLoad = false + page.on('domcontentloaded', () => { + fullPageLoad = true + }) + + await page.getByRole('link', { name: 'Open posts from SVG' }).click() + const url = `http://localhost:${PORT}/posts` + await page.waitForURL(url) + + expect(fullPageLoad).toBeFalsy() +})