Repository navigation
Expand file tree
/
Copy pathmiddleware.ts
More file actions
46 lines (41 loc) · 1.99 KB
/
Copy pathmiddleware.ts
File metadata and controls
46 lines (41 loc) · 1.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import { next, rewrite } from "@vercel/functions"
import {
MARKDOWN_FALLBACK_HEADER,
MARKDOWN_FALLBACK_PARAM,
negotiateMarkdown,
} from "./src/lib/markdown/negotiateMarkdown.js"
import { isSunsetDocsPath } from "./src/config/sunset.js"
// Vercel runs this before static HTML. Astro's src/middleware.ts does not.
// vercel.json redirects run first. Other old URLs are HTML refresh pages.
// Write the matcher as a string. Vercel reads this object as text.
// Keep it equal to the matcher exported from negotiateMarkdown.ts.
export default function middleware(request: Request): Response {
const url = new URL(request.url)
const decision = negotiateMarkdown(url.pathname, request.headers.get("accept"))
if (decision.action === "rewrite") {
const rewritten = new URL(url)
rewritten.pathname = decision.pathname
// The .md route serves HTML when this flag is set and the page has no markdown.
rewritten.searchParams.set(MARKDOWN_FALLBACK_PARAM, "1")
// Vercel keeps the original URL on the server function. That URL is the
// HTML page, and the server crashes when it tries to render it.
const headers = new Headers(request.headers)
headers.set("x-astro-path", `${rewritten.pathname}${rewritten.search}`)
headers.set(MARKDOWN_FALLBACK_HEADER, "1")
return rewrite(rewritten, { request: { headers } })
}
if (decision.action === "html") {
// Sunset pages keep their URL but are left out of Markdown output.
const headers: Record<string, string> = isSunsetDocsPath(url.pathname)
? { "X-Robots-Tag": "noindex, follow" }
: { Link: `<${decision.alternatePath}>; rel="alternate"; type="text/markdown"` }
return next({ headers })
}
return next()
}
export const config = {
matcher: [
"/((?!api/|_astro/|_image/|_vercel/|samples/)(?!.*\\.(?:avif|css|csv|eot|gif|go|gz|htm|html|ico|jpeg|jpg|js|json|map|md|mdx|mjs|mp3|mp4|otf|pdf|png|py|rs|sol|svg|toml|ts|tsx|ttf|txt|wasm|webm|webmanifest|webp|woff|woff2|xml|yaml|yml|zip)$).*)",
],
runtime: "nodejs",
}