@@ -7,18 +7,26 @@ import { toRegistrableDomain } from "@/lib/domain-server";
77export const SCHEME_PREFIX_REGEX = / ^ h t t p s ? [: / ] + ( [ ^ / ] + ) / i;
88
99export type ProxyAction =
10- | { type : "skip" }
1110 | { type : "match" }
12- | { type : "redirect" ; destination : string } ;
11+ | { type : "redirect" ; destination : string }
12+ | null ;
1313
1414/**
1515 * Pure function to decide the proxy action based on the URL path.
1616 * Decoupled from NextRequest/NextResponse for easier testing.
17+ * Returns null to skip processing (e.g. invalid domains, root path, etc).
1718 */
1819export function getProxyAction ( path : string ) : ProxyAction {
1920 // Fast path: root path or empty
2021 if ( path . length <= 1 ) {
21- return { type : "skip" } ;
22+ return null ;
23+ }
24+
25+ // Special case for OpenGraph images: /example.com/opengraph-image
26+ // This pattern is used by Next.js OG image generation for the dynamic route [domain]/opengraph-image.tsx
27+ // We should skip middleware processing for this specific suffix to allow the route to handle it.
28+ if ( path . endsWith ( "/opengraph-image" ) ) {
29+ return null ;
2230 }
2331
2432 // 1. Get raw input (remove leading slash)
@@ -61,7 +69,7 @@ export function getProxyAction(path: string): ProxyAction {
6169 // 6. Strip Port
6270 // IPv6 literals in brackets (e.g. [::1]) are not supported.
6371 if ( authority . includes ( "[" ) || authority . includes ( "]" ) ) {
64- return { type : "skip" } ;
72+ return null ;
6573 }
6674
6775 // Safe to split on colon as valid domains don't contain colons
@@ -70,14 +78,14 @@ export function getProxyAction(path: string): ProxyAction {
7078 candidate = authority . trim ( ) ;
7179
7280 if ( ! candidate ) {
73- return { type : "skip" } ;
81+ return null ;
7482 }
7583
7684 // 7. Validate and Normalize
7785 // This will return null for invalid domains, including IPs if rdapper handles them as such.
7886 const registrable = toRegistrableDomain ( candidate ) ;
7987 if ( ! registrable ) {
80- return { type : "skip" } ;
88+ return null ;
8189 }
8290
8391 // 8. Redirect if necessary
@@ -96,20 +104,25 @@ export function getProxyAction(path: string): ProxyAction {
96104export function handleProxyRequest ( request : NextRequest ) {
97105 const action = getProxyAction ( request . nextUrl . pathname ) ;
98106
99- const headers = new Headers ( ) ;
100- headers . set ( "x-middleware-decision" , action . type ) ;
107+ if ( action === null ) {
108+ return NextResponse . next ( ) ;
109+ }
101110
102111 if ( action . type === "redirect" ) {
103112 const url = request . nextUrl . clone ( ) ;
104113 url . pathname = action . destination ;
105114 url . search = "" ;
106115 url . hash = "" ;
107116 return NextResponse . redirect ( url , {
108- headers,
117+ headers : {
118+ "x-middleware-decision" : action . type ,
119+ } ,
109120 } ) ;
110121 }
111122
112123 return NextResponse . next ( {
113- headers,
124+ headers : {
125+ "x-middleware-decision" : action . type ,
126+ } ,
114127 } ) ;
115128}
0 commit comments