-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathmiddleware.ts
More file actions
77 lines (64 loc) · 2.19 KB
/
middleware.ts
File metadata and controls
77 lines (64 loc) · 2.19 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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import { rewrite } from "@vercel/functions";
import { toSiteRelativePath } from "./src/lib/site-paths";
import { resolveSiteBaseUrl, resolveSiteUrl } from "./src/lib/site-url";
/**
* Content negotiation: when a client sends Accept: text/markdown or
* Accept: text/plain, transparently rewrite to /api/markdown so it gets
* markdown instead of HTML.
*
* Keep in sync with Root.tsx MD_PREFIXES and vercel.json headers/rewrites.
* TODO: centralize content section definitions into a shared module.
*/
const SECTION_PREFIXES: Record<string, string> = {
"/docs/": "docs",
"/templates/": "templates",
"/solutions/": "solutions",
};
// Sections that have an index page (e.g., /templates → /templates.md)
const BARE_SECTIONS: Record<string, string> = {
"/templates": "templates",
"/solutions": "solutions",
};
export default function middleware(request: Request): Response | undefined {
const url = new URL(request.url);
const baseUrl = resolveSiteBaseUrl();
if (url.pathname === "/" && baseUrl !== "/") {
const redirectUrl = new URL(resolveSiteUrl());
redirectUrl.search = url.search;
return Response.redirect(redirectUrl, 307);
}
const sitePath = toSiteRelativePath(url.pathname, baseUrl);
if (sitePath !== url.pathname && sitePath.startsWith("/api/")) {
const dest = new URL(url);
dest.pathname = sitePath;
return rewrite(dest);
}
const accept = request.headers.get("accept") ?? "";
if (!accept.includes("text/markdown") && !accept.includes("text/plain"))
return undefined;
const path = url.pathname;
let section: string | undefined;
let slug = "";
for (const [prefix, sec] of Object.entries(SECTION_PREFIXES)) {
if (path.startsWith(prefix)) {
section = sec;
slug = path.slice(prefix.length).replace(/\/$/, "");
break;
}
}
if (!section) {
const bare = BARE_SECTIONS[path] ?? BARE_SECTIONS[path.replace(/\/$/, "")];
if (bare) {
section = bare;
slug = "";
}
}
if (!section) return undefined;
const dest = new URL("/api/markdown", url.origin);
dest.searchParams.set("section", section);
dest.searchParams.set("slug", slug);
return rewrite(dest);
}
export const config = {
matcher: ["/:path*"],
};