diff --git a/e2e/react-start/basic/src/routes/specialChars/hash.tsx b/e2e/react-start/basic/src/routes/specialChars/hash.tsx
index 1f1227e0207..355ad4963c2 100644
--- a/e2e/react-start/basic/src/routes/specialChars/hash.tsx
+++ b/e2e/react-start/basic/src/routes/specialChars/hash.tsx
@@ -1,4 +1,5 @@
import { createFileRoute, useLocation } from '@tanstack/react-router'
+import { useState } from 'react'
export const Route = createFileRoute('/specialChars/hash')({
component: RouteComponent,
@@ -6,10 +7,26 @@ export const Route = createFileRoute('/specialChars/hash')({
function RouteComponent() {
const l = useLocation()
+ const [toggleHashValue, setToggleHashValue] = useState(false)
return (
- Hello "/specialChars/hash"!
-
{l.hash}
+
Hello "/specialChars/hash"!
+
+
+ {toggleHashValue && (
+
+ Hash Value{l.hash}
+
+ )}
+
)
}
diff --git a/e2e/react-start/basic/src/routes/specialChars/route.tsx b/e2e/react-start/basic/src/routes/specialChars/route.tsx
index 4e75790ddd2..b15a3631660 100644
--- a/e2e/react-start/basic/src/routes/specialChars/route.tsx
+++ b/e2e/react-start/basic/src/routes/specialChars/route.tsx
@@ -46,9 +46,22 @@ function RouteComponent() {
className: 'font-bold',
}}
hash={'대|'}
- data-testid="special-hash-link"
+ data-testid="special-hash-link-1"
>
- Unicode Hash
+ Unicode Hash 대|
+ {' '}
+
+ Unicode Hash abc
{' '}
{
page,
baseURL,
}) => {
- await expect(page.getByTestId('special-hash-link')).not.toHaveClass(
+ await expect(page.getByTestId('special-hash-link-1')).not.toContainClass(
'font-bold',
)
+ await expect(page.getByTestId('special-hash-link-2')).not.toContainClass(
+ 'font-bold',
+ )
+
await page.goto('/specialChars/hash#대|')
await page.waitForURL(`${baseURL}/specialChars/hash#%EB%8C%80|`)
@@ -118,11 +122,18 @@ test.describe('Unicode route rendering', () => {
await expect(page.getByTestId('special-hash-heading')).toBeInViewport()
- const hashValue = await page.getByTestId('special-hash').textContent()
+ await expect(page.getByTestId('special-hash-link-1')).toContainClass(
+ 'font-bold',
+ )
- await expect(page.getByTestId('special-hash-link')).toHaveClass(
+ await expect(page.getByTestId('special-hash-link-2')).not.toContainClass(
'font-bold',
)
+
+ await page.getByTestId('toggle-hash-button').click()
+
+ const hashValue = await page.getByTestId('special-hash').textContent()
+
expect(hashValue).toBe('대|')
})
@@ -130,10 +141,15 @@ test.describe('Unicode route rendering', () => {
page,
baseURL,
}) => {
- await expect(page.getByTestId('special-hash-link')).not.toHaveClass(
+ await expect(page.getByTestId('special-hash-link-1')).not.toContainClass(
'font-bold',
)
- const link = page.getByTestId('special-hash-link')
+
+ await expect(page.getByTestId('special-hash-link-2')).not.toContainClass(
+ 'font-bold',
+ )
+
+ const link = page.getByTestId('special-hash-link-1')
await link.click()
@@ -142,11 +158,18 @@ test.describe('Unicode route rendering', () => {
await expect(page.getByTestId('special-hash-heading')).toBeInViewport()
- const hashValue = await page.getByTestId('special-hash').textContent()
+ await expect(page.getByTestId('special-hash-link-1')).toContainClass(
+ 'font-bold',
+ )
- await expect(page.getByTestId('special-hash-link')).toHaveClass(
+ await expect(page.getByTestId('special-hash-link-2')).not.toContainClass(
'font-bold',
)
+
+ await page.getByTestId('toggle-hash-button').click()
+
+ const hashValue = await page.getByTestId('special-hash').textContent()
+
expect(hashValue).toBe('대|')
})
})
diff --git a/e2e/solid-start/basic/src/routes/specialChars/hash.tsx b/e2e/solid-start/basic/src/routes/specialChars/hash.tsx
index 43d24ada29a..391ec1a72d4 100644
--- a/e2e/solid-start/basic/src/routes/specialChars/hash.tsx
+++ b/e2e/solid-start/basic/src/routes/specialChars/hash.tsx
@@ -1,5 +1,5 @@
import { createFileRoute, useLocation } from '@tanstack/solid-router'
-import { createEffect, createSignal } from 'solid-js'
+import { createSignal } from 'solid-js'
export const Route = createFileRoute('/specialChars/hash')({
component: RouteComponent,
@@ -7,16 +7,27 @@ export const Route = createFileRoute('/specialChars/hash')({
function RouteComponent() {
const location = useLocation()
- const [getHash, setHash] = createSignal('')
-
- createEffect(() => {
- setHash(location().hash)
- })
+ const [toggleHashValue, setToggleHashValue] = createSignal(false)
return (
- Hello "/specialChars/hash"!
-
{getHash()}
+
Hello "/specialChars/hash"!
+
+
+ {toggleHashValue() && (
+
+ Hash Value{location().hash}
+
+ )}
+
)
}
diff --git a/e2e/solid-start/basic/src/routes/specialChars/route.tsx b/e2e/solid-start/basic/src/routes/specialChars/route.tsx
index 863cb795068..e69155da677 100644
--- a/e2e/solid-start/basic/src/routes/specialChars/route.tsx
+++ b/e2e/solid-start/basic/src/routes/specialChars/route.tsx
@@ -46,10 +46,23 @@ function RouteComponent() {
class: 'font-bold',
}}
hash={'대|'}
- data-testid="special-hash-link"
+ data-testid="special-hash-link-1"
>
Unicode Hash
{' '}
+
+ Unicode Hash abc
+ {' '}
{
page,
baseURL,
}) => {
- await expect(page.getByTestId('special-hash-link')).not.toHaveClass(
+ await expect(page.getByTestId('special-hash-link-1')).not.toContainClass(
'font-bold',
)
+ await expect(page.getByTestId('special-hash-link-2')).not.toContainClass(
+ 'font-bold',
+ )
+
await page.goto('/specialChars/hash#대|')
await page.waitForURL(`${baseURL}/specialChars/hash#%EB%8C%80|`)
@@ -118,13 +122,18 @@ test.describe('Unicode route rendering', () => {
await expect(page.getByTestId('special-hash-heading')).toBeInViewport()
- const hashValue = await page.getByTestId('special-hash').textContent()
+ // TODO: this should work but seems to be a bug in reactivity on Solid Dynamic component. Still investigating.
+ // await expect(page.getByTestId('special-hash-link-1')).toContainClass(
+ // 'font-bold',
+ // )
+
+ await expect(page.getByTestId('special-hash-link-2')).not.toContainClass(
+ 'font-bold',
+ )
- const el = await page
- .getByTestId('special-hash-link')
- .evaluate((e) => e.classList.value)
+ await page.getByTestId('toggle-hash-button').click()
- expect(el).toContain('font-bold')
+ const hashValue = await page.getByTestId('special-hash').textContent()
expect(hashValue).toBe('대|')
})
@@ -133,10 +142,15 @@ test.describe('Unicode route rendering', () => {
page,
baseURL,
}) => {
- await expect(page.getByTestId('special-hash-link')).not.toHaveClass(
+ await expect(page.getByTestId('special-hash-link-1')).not.toContainClass(
'font-bold',
)
- const link = page.getByTestId('special-hash-link')
+
+ await expect(page.getByTestId('special-hash-link-2')).not.toContainClass(
+ 'font-bold',
+ )
+
+ const link = page.getByTestId('special-hash-link-1')
await link.click()
@@ -145,11 +159,18 @@ test.describe('Unicode route rendering', () => {
await expect(page.getByTestId('special-hash-heading')).toBeInViewport()
- const hashValue = await page.getByTestId('special-hash').textContent()
+ await expect(page.getByTestId('special-hash-link-1')).toContainClass(
+ 'font-bold',
+ )
- await expect(page.getByTestId('special-hash-link')).toHaveClass(
+ await expect(page.getByTestId('special-hash-link-2')).not.toContainClass(
'font-bold',
)
+
+ await page.getByTestId('toggle-hash-button').click()
+
+ const hashValue = await page.getByTestId('special-hash').textContent()
+
expect(hashValue).toBe('대|')
})
})
diff --git a/e2e/vue-start/basic/src/routes/specialChars/hash.tsx b/e2e/vue-start/basic/src/routes/specialChars/hash.tsx
index 1f76f5c7bba..d1cb9041efa 100644
--- a/e2e/vue-start/basic/src/routes/specialChars/hash.tsx
+++ b/e2e/vue-start/basic/src/routes/specialChars/hash.tsx
@@ -1,15 +1,39 @@
import { createFileRoute, useLocation } from '@tanstack/vue-router'
+import { defineComponent, ref } from 'vue'
+
+const RouteComponent = defineComponent({
+ setup() {
+ const l = useLocation()
+ const toggleHashValue = ref(false)
+
+ const toggle = () => {
+ toggleHashValue.value = !toggleHashValue.value
+ }
+
+ return () => (
+
+
Hello "/specialChars/hash"!
+
+
+ {toggleHashValue.value && (
+
+ Hash Value{l.value.hash}
+
+ )}
+
+
+ )
+ },
+})
export const Route = createFileRoute('/specialChars/hash')({
component: RouteComponent,
})
-
-function RouteComponent() {
- const l = useLocation()
- return (
-
- Hello "/specialChars/hash"!
- {l.value.hash}
-
- )
-}
diff --git a/e2e/vue-start/basic/src/routes/specialChars/route.tsx b/e2e/vue-start/basic/src/routes/specialChars/route.tsx
index b0366b65f69..86dc29d39a4 100644
--- a/e2e/vue-start/basic/src/routes/specialChars/route.tsx
+++ b/e2e/vue-start/basic/src/routes/specialChars/route.tsx
@@ -46,10 +46,23 @@ function RouteComponent() {
class: 'font-bold',
}}
hash={'대|'}
- data-testid="special-hash-link"
+ data-testid="special-hash-link-1"
>
Unicode Hash
{' '}
+
+ Unicode Hash abc
+ {' '}
{
page,
baseURL,
}) => {
- await expect(page.getByTestId('special-hash-link')).not.toHaveClass(
+ await expect(page.getByTestId('special-hash-link-1')).not.toContainClass(
'font-bold',
)
+ await expect(page.getByTestId('special-hash-link-2')).not.toContainClass(
+ 'font-bold',
+ )
+
await page.goto('/specialChars/hash#대|')
await page.waitForURL(`${baseURL}/specialChars/hash#%EB%8C%80|`)
@@ -118,11 +122,18 @@ test.describe('Unicode route rendering', () => {
await expect(page.getByTestId('special-hash-heading')).toBeInViewport()
- const hashValue = await page.getByTestId('special-hash').textContent()
+ await expect(page.getByTestId('special-hash-link-1')).toContainClass(
+ 'font-bold',
+ )
- await expect(page.getByTestId('special-hash-link')).toHaveClass(
+ await expect(page.getByTestId('special-hash-link-2')).not.toContainClass(
'font-bold',
)
+
+ await page.getByTestId('toggle-hash-button').click()
+
+ const hashValue = await page.getByTestId('special-hash').textContent()
+
expect(hashValue).toBe('대|')
})
@@ -130,10 +141,15 @@ test.describe('Unicode route rendering', () => {
page,
baseURL,
}) => {
- await expect(page.getByTestId('special-hash-link')).not.toHaveClass(
+ await expect(page.getByTestId('special-hash-link-1')).not.toContainClass(
'font-bold',
)
- const link = page.getByTestId('special-hash-link')
+
+ await expect(page.getByTestId('special-hash-link-2')).not.toContainClass(
+ 'font-bold',
+ )
+
+ const link = page.getByTestId('special-hash-link-1')
await link.click()
@@ -142,11 +158,18 @@ test.describe('Unicode route rendering', () => {
await expect(page.getByTestId('special-hash-heading')).toBeInViewport()
- const hashValue = await page.getByTestId('special-hash').textContent()
+ await expect(page.getByTestId('special-hash-link-1')).toContainClass(
+ 'font-bold',
+ )
- await expect(page.getByTestId('special-hash-link')).toHaveClass(
+ await expect(page.getByTestId('special-hash-link-2')).not.toContainClass(
'font-bold',
)
+
+ await page.getByTestId('toggle-hash-button').click()
+
+ const hashValue = await page.getByTestId('special-hash').textContent()
+
expect(hashValue).toBe('대|')
})
})
diff --git a/packages/react-router/src/link.tsx b/packages/react-router/src/link.tsx
index 72e95df0e93..31088ede192 100644
--- a/packages/react-router/src/link.tsx
+++ b/packages/react-router/src/link.tsx
@@ -13,6 +13,7 @@ import { useRouter } from './useRouter'
import { useForwardedRef, useIntersectionObserver } from './utils'
+import { useHydrated } from './ClientOnly'
import type {
AnyRouter,
Constrain,
@@ -52,6 +53,7 @@ export function useLinkProps<
const [isTransitioning, setIsTransitioning] = React.useState(false)
const hasRenderFetched = React.useRef(false)
const innerRef = useForwardedRef(forwardedRef)
+ const isHydrated = useHydrated()
const {
// custom props
@@ -225,7 +227,7 @@ export function useLinkProps<
}
if (activeOptions?.includeHash) {
- return s.location.hash === next.hash
+ return isHydrated && s.location.hash === next.hash
}
return true
},
diff --git a/packages/solid-router/src/link.tsx b/packages/solid-router/src/link.tsx
index fb1ec6e3c27..04ddc655960 100644
--- a/packages/solid-router/src/link.tsx
+++ b/packages/solid-router/src/link.tsx
@@ -230,8 +230,7 @@ export function useLinkProps<
}
}
- // url hash is not available on server, so do not evaluate this here when on server
- if (local.activeOptions?.includeHash && !router.isServer) {
+ if (local.activeOptions?.includeHash) {
return s.location.hash === next().hash
}
return true