|
1 | 1 | import { shouldServeMarkdown, generateNotFoundMarkdown } from '@vercel/agent-readability' |
| 2 | +import { trackMdRequest, extractTrackingContext, resolveSource } from '~~/server/utils/md-tracking' |
2 | 3 |
|
3 | | -const CONTENT_PREFIXES = ['/docs/', '/deploy/', '/blog/'] |
| 4 | +const SKIP_PREFIXES = ['/api/', '/_nuxt/', '/__nuxt', '/raw/', '/agent-md/'] |
| 5 | + |
| 6 | +const NOT_FOUND_OPTIONS = { |
| 7 | + baseUrl: 'https://nuxt.com', |
| 8 | + sitemapUrl: '/sitemap.md', |
| 9 | + indexUrl: '/llms.txt', |
| 10 | + fullContentUrl: '/llms-full.txt', |
| 11 | + exampleUrl: '/docs/4.x/getting-started/introduction.md' |
| 12 | +} |
| 13 | + |
| 14 | +function respondMarkdown(event: Parameters<typeof setResponseHeader>[0], body: string, reason: string) { |
| 15 | + setResponseHeader(event, 'Content-Type', 'text/markdown; charset=utf-8') |
| 16 | + setResponseHeader(event, 'Vary', 'Accept, User-Agent') |
| 17 | + setResponseHeader(event, 'X-Agent-Readability', reason) |
| 18 | + return body |
| 19 | +} |
4 | 20 |
|
5 | 21 | export default defineEventHandler(async (event) => { |
6 | 22 | const url = getRequestURL(event) |
7 | | - const pathname = url.pathname |
| 23 | + let pathname = url.pathname |
8 | 24 |
|
9 | | - if (pathname.endsWith('.md') || pathname.startsWith('/raw/')) return |
10 | | - if (pathname.startsWith('/api/') || pathname.startsWith('/_nuxt/') || pathname.startsWith('/__nuxt')) return |
| 25 | + if (SKIP_PREFIXES.some(p => pathname.startsWith(p))) return |
| 26 | + if (/\.(?:js|css|ico|png|jpg|svg|woff2|json|xml|txt)$/.test(pathname)) return |
11 | 27 |
|
12 | | - const request = toWebRequest(event) |
13 | | - const { serve, reason } = shouldServeMarkdown(request) |
14 | | - if (!serve) return |
| 28 | + if (pathname.endsWith('.md')) { |
| 29 | + pathname = pathname.slice(0, -3) |
| 30 | + } |
15 | 31 |
|
16 | | - let mdRoute: string | null = null |
| 32 | + const request = toWebRequest(event) |
| 33 | + const { serve, reason, detection } = shouldServeMarkdown(request) |
17 | 34 |
|
18 | | - for (const prefix of CONTENT_PREFIXES) { |
19 | | - if (pathname.startsWith(prefix)) { |
20 | | - mdRoute = `/raw${pathname}.md` |
21 | | - break |
22 | | - } |
23 | | - } |
| 35 | + if (!serve && !url.pathname.endsWith('.md')) return |
24 | 36 |
|
25 | | - if (!mdRoute) { |
26 | | - if (pathname === '/modules' || pathname === '/modules/') mdRoute = '/modules.md' |
27 | | - else if (pathname === '/changelog' || pathname === '/changelog/') mdRoute = '/changelog.md' |
28 | | - } |
| 37 | + const ctx = extractTrackingContext(event) |
| 38 | + const requestType = url.pathname.endsWith('.md') |
| 39 | + ? 'md-url' as const |
| 40 | + : reason === 'accept-header' |
| 41 | + ? 'header-negotiated' as const |
| 42 | + : 'agent-rewrite' as const |
29 | 43 |
|
30 | | - if (!mdRoute) return |
| 44 | + const effectiveReason = reason || 'md-url' |
31 | 45 |
|
32 | 46 | try { |
33 | | - const md = await $fetch<string>(mdRoute) |
34 | | - setResponseHeader(event, 'Content-Type', 'text/markdown; charset=utf-8') |
35 | | - setResponseHeader(event, 'Vary', 'Accept, User-Agent') |
36 | | - setResponseHeader(event, 'X-Agent-Readability', reason) |
37 | | - return md |
38 | | - } |
39 | | - catch { |
40 | | - const notFound = generateNotFoundMarkdown(pathname, { |
41 | | - baseUrl: 'https://nuxt.com', |
42 | | - sitemapUrl: '/sitemap.md', |
43 | | - indexUrl: '/llms.txt', |
44 | | - fullContentUrl: '/llms-full.txt', |
45 | | - exampleUrl: '/docs/4.x/getting-started/introduction.md' |
46 | | - }) |
47 | | - setResponseHeader(event, 'Content-Type', 'text/markdown; charset=utf-8') |
48 | | - setResponseHeader(event, 'Vary', 'Accept, User-Agent') |
49 | | - setResponseHeader(event, 'X-Agent-Readability', `${reason}-not-found`) |
50 | | - return notFound |
| 47 | + const md = await $fetch<string>(`/agent-md${pathname}`) |
| 48 | + trackMdRequest(event, { ...ctx, path: pathname, source: resolveSource(pathname), requestType, detectionMethod: detection.method }) |
| 49 | + return respondMarkdown(event, md, effectiveReason) |
| 50 | + } catch { |
| 51 | + trackMdRequest(event, { ...ctx, path: pathname, source: 'agent-404', requestType, detectionMethod: detection.method }) |
| 52 | + return respondMarkdown(event, generateNotFoundMarkdown(pathname, NOT_FOUND_OPTIONS), effectiveReason) |
51 | 53 | } |
52 | 54 | }) |
0 commit comments