Skip to content

Commit 9bb6dc2

Browse files
dengzhaofunclaude
andauthored
fix(docs): resolve relative Card hrefs from splat route (#160)
TanStack Router cannot resolve relative `to` paths (e.g. `./quickstart`) from within a catch-all splat route (/docs/$) — it outputs the current page URL unchanged, so every Card link on /docs/zh appeared to navigate nowhere. Added `FumadocsLink` wrapper in `__root.tsx` that intercepts the `href` prop before it reaches TanStack Router: if the href starts with `./` or `../`, it is resolved against `window.location.pathname` (the current URL) using the WHATWG URL parser, then passed as an absolute path to the TanStack Router `Link`. Absolute and external hrefs pass through untouched. Wire `FumadocsLink` into `<RootProvider components={{ Link: FumadocsLink }}` so fumadocs-ui's Card, sidebar, and inline links all benefit. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent c1dd681 commit 9bb6dc2

1 file changed

Lines changed: 23 additions & 1 deletion

File tree

apps/admin/src/routes/__root.tsx

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { useTenantParams } from "#/hooks/use-tenant-params";
22
import { useEffect } from 'react'
3+
import type { ComponentPropsWithRef } from 'react'
34
import { HeadContent, Scripts, createRootRoute, useRouterState, Link } from '@tanstack/react-router'
45
import { TanStackRouterDevtoolsPanel } from '@tanstack/react-router-devtools'
56
import { TanStackDevtools } from '@tanstack/react-devtools'
@@ -193,7 +194,27 @@ function RootDocument({ children }: { children: React.ReactNode }) {
193194
// 2. 避开 i18n context / useRouterState 在新旧 locale 之间的短暂抖动。
194195
// 3. 如果不在 docs 路径上(理论上不会走到,LanguageSelect 只在 DocsLayout
195196
// 里出现),降级成原地刷新。
196-
const onLocaleChange = (next: string) => {
197+
// TanStack Router cannot resolve relative `to` paths (e.g. `./quickstart`)
198+
// from a splat route (/docs/$): it outputs the current URL unchanged instead
199+
// of the intended /docs/zh/quickstart. This wrapper resolves relative hrefs
200+
// against the current pathname before handing off to TanStack Router.
201+
function FumadocsLink({ href, prefetch, ...props }: ComponentPropsWithRef<'a'> & { prefetch?: boolean }) {
202+
const currentPathname = useRouterState({ select: (s) => s.location.pathname })
203+
let resolvedHref = href ?? '#'
204+
if (href && (href.startsWith('./') || href.startsWith('../'))) {
205+
const base = currentPathname.endsWith('/') ? currentPathname : currentPathname + '/'
206+
resolvedHref = new URL(href, `https://x${base}`).pathname
207+
}
208+
return (
209+
<Link
210+
to={resolvedHref}
211+
preload={prefetch ? 'intent' : false}
212+
{...(props as object)}
213+
/>
214+
)
215+
}
216+
217+
const onLocaleChange = (next: string) => {
197218
const target = buildLocaleUrl(pathname, next)
198219
if (target !== pathname) {
199220
window.location.assign(target)
@@ -208,6 +229,7 @@ function RootDocument({ children }: { children: React.ReactNode }) {
208229
</head>
209230
<body className="font-sans antialiased [overflow-wrap:anywhere]">
210231
<RootProvider
232+
components={{ Link: FumadocsLink }}
211233
search={{
212234
options: { api: '/api/v1/search' },
213235
}}

0 commit comments

Comments
 (0)