Skip to content

Commit ed99c06

Browse files
committed
POC for serving the markdown pages (useful for LLMs)
1 parent 775ff6f commit ed99c06

File tree

4 files changed

+111
-39
lines changed

4 files changed

+111
-39
lines changed

app/api.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// app/api.ts
2+
import {
3+
createStartAPIHandler,
4+
defaultAPIFileRouteHandler,
5+
} from '@tanstack/start/api'
6+
7+
export default createStartAPIHandler(defaultAPIFileRouteHandler)

app/routes/$libraryId/$version.docs.framework.$framework.$.tsx

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { seo } from '~/utils/seo'
2-
import { createFileRoute } from '@tanstack/react-router'
2+
import { createFileRoute, redirect } from '@tanstack/react-router'
33
import { Doc } from '~/components/Doc'
44
import { loadDocs } from '~/utils/docs'
55
import { getBranch, getLibrary } from '~/libraries'
@@ -15,6 +15,20 @@ export const Route = createFileRoute(
1515

1616
const library = getLibrary(libraryId)
1717

18+
const isMarkdown = !!docsPath?.endsWith('.md')
19+
20+
if (isMarkdown) {
21+
const href =
22+
'/api/md' +
23+
ctx.location.pathname.slice(
24+
0,
25+
ctx.location.pathname.length - '.md'.length
26+
)
27+
throw redirect({
28+
href,
29+
})
30+
}
31+
1832
return loadDocs({
1933
repo: library.repo,
2034
branch: getBranch(library, version),
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { createAPIRoute } from '@tanstack/start/api'
2+
import { getBranch, getLibrary } from '~/libraries'
3+
import { loadDocs } from '~/utils/docs'
4+
5+
export const APIRoute = createAPIRoute('/api/md/$libraryId/$version/docs/framework/$framework/$')({
6+
GET: async ({ params, request }) => {
7+
const { libraryId, version, framework, _splat: docsPath } = params
8+
const library = getLibrary(libraryId)
9+
10+
const location = new URL(request.url)
11+
12+
const loadDocsArgs = {
13+
repo: library.repo,
14+
branch: getBranch(library, version),
15+
docsPath: `${
16+
library.docsRoot || 'docs'
17+
}/framework/${framework}/${docsPath}`,
18+
currentPath: location.pathname.slice('/api/md'.length),
19+
redirectPath: `/${library.id}/${version}/docs/overview`,
20+
useServerFn: false
21+
}
22+
23+
const res = await loadDocs(loadDocsArgs)
24+
25+
26+
const { content, description, title} = res
27+
28+
// Generate or fetch the Markdown content dynamically
29+
const markdownContent = `# ${title}\n\n> ${description}\n\n${content}`
30+
31+
// Return the Markdown content as a response
32+
return new Response(markdownContent, {
33+
headers: {
34+
'Content-Type': 'text/markdown',
35+
},
36+
})
37+
},
38+
})

app/utils/docs.ts

Lines changed: 51 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,27 @@ import { createServerFn } from '@tanstack/start'
99
import { z } from 'zod'
1010
import { setHeader } from 'vinxi/http'
1111

12+
const FetchDocsDataSchema = z.object({
13+
repo: z.string(),
14+
branch: z.string(),
15+
filePath: z.string(),
16+
})
17+
type FetchDocsData = z.infer<typeof FetchDocsDataSchema>
18+
1219
export const loadDocs = async ({
1320
repo,
1421
branch,
1522
// currentPath,
1623
// redirectPath,
1724
docsPath,
25+
useServerFn = true,
1826
}: {
1927
repo: string
2028
branch: string
2129
docsPath: string
2230
currentPath: string
2331
redirectPath: string
32+
useServerFn?: boolean
2433
}) => {
2534
if (!branch) {
2635
throw new Error('Invalid branch')
@@ -32,55 +41,59 @@ export const loadDocs = async ({
3241

3342
const filePath = `${docsPath}.md`
3443

35-
return await fetchDocs({
44+
const params: { data: FetchDocsData } = {
3645
data: {
3746
repo,
3847
branch,
3948
filePath,
40-
// currentPath,
41-
// redirectPath,
4249
},
43-
})
50+
}
51+
52+
return useServerFn ? fetchDocs(params) : fetchDocsFunction(params)
4453
}
4554

46-
export const fetchDocs = createServerFn({ method: 'GET' })
47-
.validator(
48-
z.object({ repo: z.string(), branch: z.string(), filePath: z.string() })
49-
)
50-
.handler(async ({ data: { repo, branch, filePath } }) => {
51-
const file = await fetchRepoFile(repo, branch, filePath)
55+
const fetchDocsFunction = async ({
56+
data: { repo, branch, filePath },
57+
}: {
58+
data: FetchDocsData
59+
}) => {
60+
const file = await fetchRepoFile(repo, branch, filePath)
61+
62+
if (!file) {
63+
throw notFound()
64+
// if (currentPath === redirectPath) {
65+
// // console.log('not found')
66+
// throw notFound()
67+
// } else {
68+
// // console.log('redirect')
69+
// throw redirect({
70+
// to: redirectPath,
71+
// })
72+
// }
73+
}
5274

53-
if (!file) {
54-
throw notFound()
55-
// if (currentPath === redirectPath) {
56-
// // console.log('not found')
57-
// throw notFound()
58-
// } else {
59-
// // console.log('redirect')
60-
// throw redirect({
61-
// to: redirectPath,
62-
// })
63-
// }
64-
}
75+
const frontMatter = extractFrontMatter(file)
76+
const description = removeMarkdown(frontMatter.excerpt ?? '')
6577

66-
const frontMatter = extractFrontMatter(file)
67-
const description = removeMarkdown(frontMatter.excerpt ?? '')
78+
// Cache for 5 minutes on shared cache
79+
// Revalidate in the background
80+
setHeader('Cache-Control', 'public, max-age=0, must-revalidate')
81+
setHeader(
82+
'CDN-Cache-Control',
83+
'max-age=300, stale-while-revalidate=300, durable'
84+
)
6885

69-
// Cache for 5 minutes on shared cache
70-
// Revalidate in the background
71-
setHeader('Cache-Control', 'public, max-age=0, must-revalidate')
72-
setHeader(
73-
'CDN-Cache-Control',
74-
'max-age=300, stale-while-revalidate=300, durable'
75-
)
86+
return {
87+
title: frontMatter.data?.title,
88+
description,
89+
filePath,
90+
content: frontMatter.content,
91+
}
92+
}
7693

77-
return {
78-
title: frontMatter.data?.title,
79-
description,
80-
filePath,
81-
content: frontMatter.content,
82-
}
83-
})
94+
export const fetchDocs = createServerFn({ method: 'GET' })
95+
.validator(FetchDocsDataSchema)
96+
.handler(fetchDocsFunction)
8497

8598
export const fetchFile = createServerFn({ method: 'GET' })
8699
.validator(

0 commit comments

Comments
 (0)