Repository navigation
Expand file tree
/
Copy pathproxy.ts
More file actions
59 lines (51 loc) · 2.13 KB
/
Copy pathproxy.ts
File metadata and controls
59 lines (51 loc) · 2.13 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
import { NextResponse, type NextRequest } from 'next/server';
import { EDGE_LOGGED_HEADER, logEdgeDoc } from '@/lib/log';
/**
* Runs before routing (Next 16 renamed the `middleware` convention to
* `proxy`). Two jobs, both narrow:
*
* 1. Markdown content negotiation for the homepage. Any request for `/` that
* does not explicitly prefer text/markdown falls straight through to the
* normal HTML response. The only unconditional change is the Vary header,
* which is required once one URL can answer in two formats — without it a
* CDN can hand an agent the cached HTML, or a browser the cached Markdown.
*
* 2. Counting machine-doc reads. These docs are static or CDN-cached, so their
* route code does not run per request and cannot log them. The proxy sees
* every hit: it logs one line synchronously, leaves the analytics event to
* after(), and never changes the response, so caching is unaffected.
*/
export function proxy(request: NextRequest) {
const { pathname } = request.nextUrl;
if (pathname === '/') {
const accept = request.headers.get('accept') ?? '';
const wantsMarkdown =
accept.includes('text/markdown') && !accept.includes('text/html');
const response = wantsMarkdown
? NextResponse.rewrite(new URL('/index.md', request.url))
: NextResponse.next();
response.headers.set('Vary', 'Accept, Accept-Encoding');
if (wantsMarkdown && request.method === 'GET') logEdgeDoc('/', request);
return response;
}
// Count reads only: CORS preflights and HEAD checks are not consumption.
if (request.method !== 'GET') return NextResponse.next();
logEdgeDoc(pathname, request);
// Tell a route handler behind this (e.g. /agents.json) that the hit is
// already counted. Upstream request headers only; the response is untouched.
const forwarded = new Headers(request.headers);
forwarded.set(EDGE_LOGGED_HEADER, '1');
return NextResponse.next({ request: { headers: forwarded } });
}
export const config = {
matcher: [
'/',
'/llms.txt',
'/agents.json',
'/index.md',
'/skill.md',
'/SKILL.md',
'/openapi.json',
'/.well-known/:path*',
],
};