diff --git a/packages/react-router/src/link.tsx b/packages/react-router/src/link.tsx
index f5d2b987652..2d4c2a60daf 100644
--- a/packages/react-router/src/link.tsx
+++ b/packages/react-router/src/link.tsx
@@ -120,13 +120,13 @@ export function useLinkProps<
let external = false
if (router.origin) {
if (href.startsWith(router.origin)) {
- href = href.replace(router.origin, '') || '/'
+ href = router.history.createHref(href.replace(router.origin, '')) || '/'
} else {
external = true
}
}
return { href, external }
- }, [disabled, next.maskedLocation, next.url, router.origin])
+ }, [disabled, next.maskedLocation, next.url, router.origin, router.history])
const externalLink = React.useMemo(() => {
if (hrefOption?.external) {
diff --git a/packages/react-router/tests/link.test.tsx b/packages/react-router/tests/link.test.tsx
index d0c1d79b119..e9ca9564a62 100644
--- a/packages/react-router/tests/link.test.tsx
+++ b/packages/react-router/tests/link.test.tsx
@@ -17,6 +17,7 @@ import {
Outlet,
RouterProvider,
createBrowserHistory,
+ createHashHistory,
createLink,
createMemoryHistory,
createRootRoute,
@@ -6335,3 +6336,55 @@ describe('rewrite', () => {
expect(appLink).toHaveAttribute('href', 'http://app.example.com/')
})
})
+
+describe('hash history with target="_blank" links', () => {
+ test('should generate correct href for target="_blank" links in hash history mode', async () => {
+ const hashHistory = createHashHistory()
+
+ const rootRoute = createRootRoute()
+ const indexRoute = createRoute({
+ getParentRoute: () => rootRoute,
+ path: '/',
+ component: () => {
+ return (
+ <>
+
Index
+
+ Posts (same tab)
+
+
+ About (new tab)
+
+ >
+ )
+ },
+ })
+
+ const postsRoute = createRoute({
+ getParentRoute: () => rootRoute,
+ path: '/posts',
+ component: () => Posts
,
+ })
+
+ const aboutRoute = createRoute({
+ getParentRoute: () => rootRoute,
+ path: '/about',
+ component: () => About
,
+ })
+
+ const router = createRouter({
+ routeTree: rootRoute.addChildren([indexRoute, postsRoute, aboutRoute]),
+ history: hashHistory,
+ })
+
+ render()
+
+ const postsLink = await screen.findByTestId('posts-link')
+ expect(postsLink).toHaveAttribute('href', '/#/posts')
+ expect(postsLink).not.toHaveAttribute('target', '_blank')
+
+ const postsBlankLink = await screen.findByTestId('about-blank-link')
+ expect(postsBlankLink).toHaveAttribute('href', '/#/about')
+ expect(postsBlankLink).toHaveAttribute('target', '_blank')
+ })
+})
diff --git a/packages/solid-router/src/link.tsx b/packages/solid-router/src/link.tsx
index ca0b70b9381..407f106d36b 100644
--- a/packages/solid-router/src/link.tsx
+++ b/packages/solid-router/src/link.tsx
@@ -146,7 +146,7 @@ export function useLinkProps<
let external = false
if (router.origin) {
if (href.startsWith(router.origin)) {
- href = href.replace(router.origin, '')
+ href = router.history.createHref(href.replace(router.origin, ''))
} else {
external = true
}
diff --git a/packages/solid-router/tests/link.test.tsx b/packages/solid-router/tests/link.test.tsx
index e06100edf3b..b80bcb9442d 100644
--- a/packages/solid-router/tests/link.test.tsx
+++ b/packages/solid-router/tests/link.test.tsx
@@ -15,6 +15,7 @@ import {
Outlet,
RouterProvider,
createBrowserHistory,
+ createHashHistory,
createLink,
createMemoryHistory,
createRootRoute,
@@ -5674,3 +5675,55 @@ describe('relative links to from route', () => {
},
)
})
+
+describe('hash history with target="_blank" links', () => {
+ test('should generate correct href for target="_blank" links in hash history mode', async () => {
+ const hashHistory = createHashHistory()
+
+ const rootRoute = createRootRoute()
+ const indexRoute = createRoute({
+ getParentRoute: () => rootRoute,
+ path: '/',
+ component: () => {
+ return (
+ <>
+ Index
+
+ Posts (same tab)
+
+
+ About (new tab)
+
+ >
+ )
+ },
+ })
+
+ const postsRoute = createRoute({
+ getParentRoute: () => rootRoute,
+ path: '/posts',
+ component: () => Posts
,
+ })
+
+ const aboutRoute = createRoute({
+ getParentRoute: () => rootRoute,
+ path: '/about',
+ component: () => About
,
+ })
+
+ const router = createRouter({
+ routeTree: rootRoute.addChildren([indexRoute, postsRoute, aboutRoute]),
+ history: hashHistory,
+ })
+
+ render(() => )
+
+ const postsLink = await screen.findByTestId('posts-link')
+ expect(postsLink).toHaveAttribute('href', '/#/posts')
+ expect(postsLink).not.toHaveAttribute('target', '_blank')
+
+ const postsBlankLink = await screen.findByTestId('about-blank-link')
+ expect(postsBlankLink).toHaveAttribute('href', '/#/about')
+ expect(postsBlankLink).toHaveAttribute('target', '_blank')
+ })
+})