Skip to content

Commit 86792c8

Browse files
committed
fix: preserve library params in docs links
Pass library and version params explicitly in landing and docs navigation links so static landing routes resolve the right destinations. This avoids undefined home/docs URLs after the landing route split.
1 parent 3d8fb97 commit 86792c8

13 files changed

Lines changed: 97 additions & 47 deletions

src/components/BackgroundGradient.tsx

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,19 @@
11
import { twMerge } from 'tailwind-merge'
2-
import { useMatches, useParams } from '@tanstack/react-router'
2+
import { useLocation, useParams } from '@tanstack/react-router'
33
import { findLibrary } from '~/libraries'
44

55
export function BackgroundGradient() {
66
let libraryId = useParams({
77
select: (p) => p.libraryId,
88
strict: false,
99
}) as string
10-
11-
const matches = useMatches()
10+
const location = useLocation()
1211

1312
if (!libraryId) {
14-
const matchIndex = matches.findIndex((m) => m.routeId === '/_libraries')
15-
const match = matches[matchIndex + 1]
16-
if (match) {
17-
// Route ID format: /_libraries/query/$version/ -> split gives ['', '_libraries', 'query', '$version', '']
18-
libraryId = match.routeId.split('/')[2]
13+
const pathnameLibraryId = location.pathname.split('/')[1]
14+
15+
if (pathnameLibraryId) {
16+
libraryId = pathnameLibraryId
1917
}
2018
}
2119

src/components/DocsLayout.tsx

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,8 @@ export const useWidthToggle = () => {
341341
// Create context for doc navigation (prev/next)
342342
type DocNavItem = { label: React.ReactNode; to: string }
343343
const DocNavigationContext = React.createContext<{
344+
libraryId: LibraryId
345+
version: string
344346
prevItem?: DocNavItem
345347
nextItem?: DocNavItem
346348
colorFrom: string
@@ -356,7 +358,15 @@ export function DocNavigation() {
356358
const context = useDocNavigation()
357359
if (!context) return null
358360

359-
const { prevItem, nextItem, colorFrom, colorTo, textColor } = context
361+
const {
362+
libraryId,
363+
version,
364+
prevItem,
365+
nextItem,
366+
colorFrom,
367+
colorTo,
368+
textColor,
369+
} = context
360370

361371
if (!prevItem && !nextItem) return null
362372

@@ -368,7 +378,7 @@ export function DocNavigation() {
368378
as={Link}
369379
from="/$libraryId/$version/docs"
370380
to={prevItem.to}
371-
params
381+
params={{ libraryId, version } as never}
372382
className="py-1 px-2 sm:py-2 sm:px-3 flex items-center gap-1 sm:gap-2"
373383
>
374384
<ChevronLeft className="w-3 h-3 sm:w-4 sm:h-4" />
@@ -387,7 +397,7 @@ export function DocNavigation() {
387397
as={Link}
388398
from="/$libraryId/$version/docs"
389399
to={nextItem.to}
390-
params
400+
params={{ libraryId, version } as never}
391401
className="py-1 px-2 sm:py-2 sm:px-3 flex items-center gap-1 sm:gap-2"
392402
>
393403
<div className="flex flex-col items-end">
@@ -651,6 +661,10 @@ export function DocsLayout({
651661
<ul className="text-[.85em] leading-snug list-none">
652662
{group?.children?.map((child, i) => {
653663
const linkClasses = `flex gap-2 items-center justify-between group px-2 py-1.5 rounded-lg hover:bg-gray-500/10 opacity-60 hover:opacity-100`
664+
const linkParams =
665+
!child.to.startsWith('/') || child.to.includes('/$libraryId')
666+
? ({ libraryId, version } as never)
667+
: undefined
654668

655669
return (
656670
<li key={i}>
@@ -667,7 +681,7 @@ export function DocsLayout({
667681
<Link
668682
from="/$libraryId/$version/docs"
669683
to={child.to}
670-
params
684+
params={linkParams}
671685
onClick={() => {
672686
detailsRef.current.removeAttribute('open')
673687
}}
@@ -877,7 +891,15 @@ export function DocsLayout({
877891
return (
878892
<WidthToggleContext.Provider value={{ isFullWidth, setIsFullWidth }}>
879893
<DocNavigationContext.Provider
880-
value={{ prevItem, nextItem, colorFrom, colorTo, textColor }}
894+
value={{
895+
libraryId,
896+
version,
897+
prevItem,
898+
nextItem,
899+
colorFrom,
900+
colorTo,
901+
textColor,
902+
}}
881903
>
882904
<div
883905
className={`

src/components/FrameworkCard.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Link } from '@tanstack/react-router'
22
import { twMerge } from 'tailwind-merge'
3-
import { Library } from '~/libraries'
3+
import type { Library, LibraryId } from '~/libraries'
44
import { getFrameworkOptions } from '~/libraries/frameworks'
55
import { useCopyButton } from '~/components/CopyMarkdownButton'
66
import { useToast } from '~/components/ToastProvider'
@@ -10,12 +10,14 @@ import { Card } from '~/components/Card'
1010
export function FrameworkCard({
1111
framework,
1212
libraryId,
13+
version,
1314
packageName,
1415
index,
1516
library,
1617
}: {
1718
framework: ReturnType<typeof getFrameworkOptions>[number]
18-
libraryId: string
19+
libraryId: LibraryId
20+
version: string
1921
packageName: string
2022
index: number
2123
library: Library
@@ -62,6 +64,8 @@ export function FrameworkCard({
6264
from="/$libraryId/$version/docs"
6365
to="./$"
6466
params={{
67+
libraryId,
68+
version,
6569
_splat: installationPath,
6670
}}
6771
hash={installationHash}
@@ -111,6 +115,8 @@ export function FrameworkCard({
111115
from="/$libraryId/$version/docs"
112116
to="./$"
113117
params={{
118+
libraryId,
119+
version,
114120
_splat: installationPath,
115121
}}
116122
hash={installationHash}

src/components/landing/CliLanding.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Link } from '@tanstack/react-router'
1+
import { Link, useParams } from '@tanstack/react-router'
22
import { Layers } from 'lucide-react'
33
import { Footer } from '~/components/Footer'
44
import { LazySponsorSection } from '~/components/LazySponsorSection'
@@ -16,6 +16,8 @@ import { LazyLandingCommunitySection } from '~/components/LazyLandingCommunitySe
1616
const library = getLibrary('cli')
1717

1818
export default function CliLanding() {
19+
const { version } = useParams({ strict: false })
20+
1921
return (
2022
<LibraryPageContainer>
2123
<LibraryHero
@@ -32,7 +34,7 @@ export default function CliLanding() {
3234
</Button>
3335
<Button
3436
as="a"
35-
href="/cli/latest/docs"
37+
href={`/cli/${version}/docs`}
3638
className="bg-indigo-500 border-indigo-500 hover:bg-indigo-600 dark:bg-indigo-600 dark:border-indigo-600 text-white"
3739
>
3840
Get Started
@@ -58,7 +60,7 @@ export default function CliLanding() {
5860
<BottomCTA
5961
linkProps={{
6062
to: '/$libraryId/$version/docs',
61-
params: { libraryId: library.id },
63+
params: { libraryId: library.id, version },
6264
}}
6365
label="Get Started!"
6466
className="bg-indigo-500 border-indigo-500 hover:bg-indigo-600 text-white"

src/components/landing/ConfigLanding.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { useParams } from '@tanstack/react-router'
12
import { Footer } from '~/components/Footer'
23
import { LazySponsorSection } from '~/components/LazySponsorSection'
34
import { LibraryHero } from '~/components/LibraryHero'
@@ -15,14 +16,16 @@ import { LazyLandingCommunitySection } from '~/components/LazyLandingCommunitySe
1516
const library = getLibrary('config')
1617

1718
export default function ConfigLanding() {
19+
const { version } = useParams({ strict: false })
20+
1821
return (
1922
<LibraryPageContainer>
2023
<LibraryHero
2124
project={configProject}
2225
actions={
2326
<Button
2427
as="a"
25-
href={`/config/latest/docs`}
28+
href={`/config/${version}/docs`}
2629
className="bg-gray-500 border-gray-500 hover:bg-gray-600 text-white"
2730
>
2831
Get Started
@@ -72,7 +75,7 @@ export default function ConfigLanding() {
7275
<BottomCTA
7376
linkProps={{
7477
to: '/$libraryId/$version/docs',
75-
params: { libraryId: library.id },
78+
params: { libraryId: library.id, version },
7679
}}
7780
label="Get Started!"
7881
className="bg-gray-500 border-gray-500 hover:bg-gray-600 text-white"

src/components/landing/DbLanding.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { useParams } from '@tanstack/react-router'
12
import { Footer } from '~/components/Footer'
23
import { LazySponsorSection } from '~/components/LazySponsorSection'
34
import { BottomCTA } from '~/components/BottomCTA'
@@ -13,14 +14,16 @@ import { LazyLandingCommunitySection } from '~/components/LazyLandingCommunitySe
1314
const library = getLibrary('db')
1415

1516
export default function DbLanding() {
17+
const { version } = useParams({ strict: false })
18+
1619
return (
1720
<LibraryPageContainer>
1821
<LibraryHero
1922
project={dbProject}
2023
cta={{
2124
linkProps: {
2225
to: '/$libraryId/$version/docs',
23-
params: { libraryId: library.id },
26+
params: { libraryId: library.id, version },
2427
},
2528
label: 'Get Started',
2629
className:
@@ -82,7 +85,7 @@ export default function DbLanding() {
8285
<BottomCTA
8386
linkProps={{
8487
to: '/$libraryId/$version/docs',
85-
params: { libraryId: library.id },
88+
params: { libraryId: library.id, version },
8689
}}
8790
label="Get Started!"
8891
className="bg-orange-500 border-orange-500 hover:bg-orange-600 text-white"

src/components/landing/DevtoolsLanding.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { useParams } from '@tanstack/react-router'
12
import { Footer } from '~/components/Footer'
23
import { LazySponsorSection } from '~/components/LazySponsorSection'
34
import { BottomCTA } from '~/components/BottomCTA'
@@ -14,14 +15,16 @@ import { LazyLandingCommunitySection } from '~/components/LazyLandingCommunitySe
1415
const library = getLibrary('devtools')
1516

1617
export default function DevtoolsLanding() {
18+
const { version } = useParams({ strict: false })
19+
1720
return (
1821
<LibraryPageContainer>
1922
<LibraryHero
2023
project={devtoolsProject}
2124
cta={{
2225
linkProps: {
2326
to: '/$libraryId/$version/docs',
24-
params: { libraryId: library.id },
27+
params: { libraryId: library.id, version },
2528
},
2629
label: 'Get Started',
2730
className:
@@ -74,7 +77,7 @@ export default function DevtoolsLanding() {
7477
<BottomCTA
7578
linkProps={{
7679
to: '/$libraryId/$version/docs',
77-
params: { libraryId: library.id },
80+
params: { libraryId: library.id, version },
7881
}}
7982
label="Get Started!"
8083
className="bg-slate-500 border-slate-500 hover:bg-slate-600 hover:border-slate-600 text-white"

src/components/landing/HotkeysLanding.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as React from 'react'
2-
import { ClientOnly } from '@tanstack/react-router'
2+
import { ClientOnly, useParams } from '@tanstack/react-router'
33
import { Footer } from '~/components/Footer'
44
import { LibraryHero } from '~/components/LibraryHero'
55
import { LazySponsorSection } from '~/components/LazySponsorSection'
@@ -22,6 +22,8 @@ const LazyHotkeysShortcutBinding = React.lazy(() =>
2222
)
2323

2424
export default function HotkeysLanding() {
25+
const { version } = useParams({ strict: false })
26+
2527
return (
2628
<LibraryPageContainer>
2729
<ClientOnly>
@@ -34,7 +36,7 @@ export default function HotkeysLanding() {
3436
cta={{
3537
linkProps: {
3638
to: '/$libraryId/$version/docs',
37-
params: { libraryId: library.id, version: 'latest' },
39+
params: { libraryId: library.id, version },
3840
},
3941
label: (
4042
<>
@@ -85,7 +87,7 @@ export default function HotkeysLanding() {
8587
<BottomCTA
8688
linkProps={{
8789
to: '/$libraryId/$version/docs',
88-
params: { libraryId: library.id },
90+
params: { libraryId: library.id, version },
8991
}}
9092
label="Get Started!"
9193
className="bg-rose-600 border-rose-600 hover:bg-rose-700 hover:border-rose-700 text-white"

src/components/landing/IntentLanding.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as React from 'react'
2-
import { Link, useNavigate } from '@tanstack/react-router'
2+
import { Link, useNavigate, useParams } from '@tanstack/react-router'
33
import { useQuery } from '@tanstack/react-query'
44
import { Footer } from '~/components/Footer'
55
import { LazySponsorSection } from '~/components/LazySponsorSection'
@@ -24,6 +24,8 @@ import type { SkillHistoryEntry } from '~/utils/intent.functions'
2424
const library = getLibrary('intent')
2525

2626
export default function IntentLanding() {
27+
const { version } = useParams({ strict: false })
28+
2729
return (
2830
<LibraryPageContainer>
2931
<LibraryHero
@@ -39,9 +41,8 @@ export default function IntentLanding() {
3941
</Button>
4042
<Button
4143
as={Link}
42-
from="/$libraryId/$version"
43-
to="./docs"
44-
params={{ libraryId: library.id } as never}
44+
to="/$libraryId/$version/docs"
45+
params={{ libraryId: library.id, version } as never}
4546
className="bg-sky-500 border-sky-500 hover:bg-sky-600 dark:bg-sky-600 dark:border-sky-600 text-white"
4647
>
4748
Get Started
@@ -69,7 +70,7 @@ export default function IntentLanding() {
6970
<BottomCTA
7071
linkProps={{
7172
to: '/$libraryId/$version/docs',
72-
params: { libraryId: library.id },
73+
params: { libraryId: library.id, version },
7374
}}
7475
label="Get Started!"
7576
className="bg-sky-500 border-sky-500 hover:bg-sky-600 text-white"

src/components/landing/PacerLanding.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { useParams } from '@tanstack/react-router'
12
import { Footer } from '~/components/Footer'
23
import { LibraryHero } from '~/components/LibraryHero'
34
import { LazySponsorSection } from '~/components/LazySponsorSection'
@@ -14,14 +15,16 @@ import { LazyLandingCommunitySection } from '~/components/LazyLandingCommunitySe
1415
const library = getLibrary('pacer')
1516

1617
export default function PacerLanding() {
18+
const { version } = useParams({ strict: false })
19+
1720
return (
1821
<LibraryPageContainer>
1922
<LibraryHero
2023
project={pacerProject}
2124
cta={{
2225
linkProps: {
2326
to: '/$libraryId/$version/docs',
24-
params: { libraryId: library.id },
27+
params: { libraryId: library.id, version },
2528
},
2629
label: 'Get Started',
2730
className: 'bg-lime-600 border-lime-600 hover:bg-lime-700 text-white',
@@ -72,7 +75,7 @@ export default function PacerLanding() {
7275
<BottomCTA
7376
linkProps={{
7477
to: '/$libraryId/$version/docs',
75-
params: { libraryId: library.id },
78+
params: { libraryId: library.id, version },
7679
}}
7780
label="Get Started!"
7881
className="bg-lime-600 border-lime-600 hover:bg-lime-700 hover:border-lime-700 text-white"

0 commit comments

Comments
 (0)