Repository navigation
Expand file tree
/
Copy pathproxy.ts
More file actions
70 lines (53 loc) · 2.18 KB
/
Copy pathproxy.ts
File metadata and controls
70 lines (53 loc) · 2.18 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
import { NextRequest, NextResponse } from 'next/server'
import { resolveBlogListingUrl } from '@/lib/blog/listing'
import { fetchRedirect } from '@/lib/redirects/redirectCache'
/** Paths that must never be redirected, regardless of stored rows. */
const REDIRECT_EXEMPT = ['/admin', '/api', '/_next', '/next']
/**
* Resolves a redirect for the current request.
*
* Runs in-process: `proxy.ts` is on the Node runtime, so Payload loads here
* directly. Results are memoized in the KV store and invalidated by the
* Redirects collection hooks.
*
* Failures are swallowed: a redirect lookup must never take down a page.
*/
const lookupRedirect = async (request: NextRequest) => {
const { pathname } = request.nextUrl
if (REDIRECT_EXEMPT.some((prefix) => pathname.startsWith(prefix))) return null
try {
const redirect = await fetchRedirect(pathname)
if (redirect && redirect.destination !== pathname) return redirect
return null
} catch {
return null
}
}
export default async function proxy(request: NextRequest) {
const redirect = await lookupRedirect(request)
if (redirect) {
const destination = new URL(redirect.destination, request.url)
// preserve the incoming query string unless the target defines its own
if (!redirect.destination.includes('?')) {
destination.search = request.nextUrl.search
}
return NextResponse.redirect(destination, redirect.statusCode)
}
/**
* Blog listings paginate and sort via `?page=` / `?sort=`. Non-canonical
* forms (`page=1`, unknown sorts, …) redirect to their canonical URL here:
* the listing reads its params inside a Suspense boundary, where it can no
* longer change the response status.
*/
const listing = resolveBlogListingUrl(request.nextUrl.pathname, request.nextUrl.search)
if (listing?.redirect) {
return NextResponse.redirect(new URL(listing.redirect, request.url), 308)
}
const response = NextResponse.next()
// alternative sort orders duplicate the default listing's content
if (listing && !listing.indexable) {
response.headers.set('X-Robots-Tag', 'noindex, follow')
}
response.headers.set('X-Current-Path', request.nextUrl.pathname)
return response
}