-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmiddleware.js
More file actions
111 lines (95 loc) · 3.98 KB
/
Copy pathmiddleware.js
File metadata and controls
111 lines (95 loc) · 3.98 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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// Markdown content negotiation (acceptmarkdown.com).
//
// Agents that send `Accept: text/markdown` get the markdown rendition of a
// page; browsers get the HTML. `Vary: Accept` is set on BOTH variants, without
// which a CDN can hand the cached HTML to an agent (or vice versa) depending on
// which variant happened to land in cache first.
//
// This is the one agent-readiness signal a purely static host cannot provide,
// because it requires code to run on the request.
// Catch-all except requests for files with an extension, so static assets
// (og.png, llms.txt, sitemap.xml, *.md) are served directly and untouched.
export const config = {
matcher: ["/((?!.*\\.[a-zA-Z0-9]+$).*)"],
};
// Paths that really exist. Anything else is a 404, and an agent asking for
// markdown gets a markdown recovery page instead of an HTML one.
const KNOWN = new Set([
"/", "/index.html",
"/about", "/about.html",
"/contact", "/contact.html",
"/privacy", "/privacy.html",
]);
const NOT_FOUND_MD = `# 404 — page not found
That path does not exist on this site. Everything that does exist is listed
below, so you can recover without guessing.
## Pages
- [Home](https://defluffer.vercel.app/) — what defluffer is, a demo, and examples
- [About](https://defluffer.vercel.app/about) — what it does, how it is built, who made it
- [Contact](https://defluffer.vercel.app/contact) — support, bug reports, press
- [Privacy](https://defluffer.vercel.app/privacy) — exactly what data is handled
## Machine-readable
- [llms.txt](https://defluffer.vercel.app/llms.txt) — description and when-to-use guidance for agents
- [sitemap.xml](https://defluffer.vercel.app/sitemap.xml) — every indexable URL
- [robots.txt](https://defluffer.vercel.app/robots.txt) — crawl policy (all agents allowed)
## Install
- [Chrome Web Store](https://chromewebstore.google.com/detail/defluffer/ofaajilnnjfcinocgpljpmchpcnbhhln)
- [Firefox Add-ons](https://addons.mozilla.org/en-US/firefox/addon/defluffer/)
- [Source code, MIT](https://github.com/itayzit/defluffer)
`;
const MARKDOWN_FOR = {
"/": "/index.md",
"/index.html": "/index.md",
"/about": "/about.md",
"/about.html": "/about.md",
"/contact": "/contact.md",
"/contact.html": "/contact.md",
"/privacy": "/privacy.md",
"/privacy.html": "/privacy.md",
};
// Honour the quality values in Accept rather than a bare substring match, so a
// browser sending `text/markdown;q=0.1` after text/html still gets HTML.
function prefersMarkdown(accept) {
if (!accept) return false;
let md = 0;
let html = 0;
for (const part of accept.split(",")) {
const [type, ...params] = part.trim().split(";");
const q = params.reduce((acc, p) => {
const m = p.trim().match(/^q=([\d.]+)$/);
return m ? parseFloat(m[1]) : acc;
}, 1);
const t = type.trim().toLowerCase();
if (t === "text/markdown" || t === "text/x-markdown") md = Math.max(md, q);
if (t === "text/html" || t === "application/xhtml+xml") html = Math.max(html, q);
}
return md > 0 && md >= html;
}
export default function middleware(request) {
const url = new URL(request.url);
const target = MARKDOWN_FOR[url.pathname];
if (target && prefersMarkdown(request.headers.get("accept"))) {
const rewritten = new URL(target, url);
return new Response(null, {
headers: {
"x-middleware-rewrite": rewritten.toString(),
Vary: "Accept, Accept-Encoding",
},
});
}
// Unknown path: still a real 404, but hand agents a markdown recovery page
// (site map + llms.txt) rather than an HTML one they have to parse.
if (!KNOWN.has(url.pathname) && prefersMarkdown(request.headers.get("accept"))) {
return new Response(NOT_FOUND_MD, {
status: 404,
headers: {
"Content-Type": "text/markdown; charset=utf-8",
Vary: "Accept, Accept-Encoding",
},
});
}
// Pass through, but still declare that this URL varies on Accept.
return new Response(null, {
headers: { "x-middleware-next": "1", Vary: "Accept, Accept-Encoding" },
});
}