The Full Request Routing Order
Hard · Config
For every request, Next.js checks routing features in a fixed order (documented on the rewrites and proxy pages):
1. headers from next.config
2. redirects
3. Proxy (proxy.ts)
4. beforeFiles rewrites
5. static files from public/ and non-dynamic pages
6. afterFiles rewrites
7. dynamic routes (like /blog/[slug])
8. fallback rewrites
Write resolveRequest(config, url) that follows this order. This is a simplified model of the routing pipeline. url is a path (a query string is ignored). The proxy is given as data rules. Patterns support literal segments, :name (one segment) and :name* (the rest), and destinations reuse the params (an empty :name* disappears with its slash).
- Headers: every rule whose source matches the original path adds its headers (lowercase names, later rules overwrite). Step "headers <source>".
- Redirects: the first match returns a redirect with status 308 (permanent) or 307. Step "redirect <source>".
- Proxy: only the first matching rule runs. Step "proxy <action> <source>"; its headers are added. redirect returns a 307 redirect, rewrite changes the path, next does nothing else.
- beforeFiles: every rule is checked in order against the current path, and each match rewrites it (step "beforeFiles <source> -> <new path>"), without checking files in between.
- Filesystem: a path listed in publicFiles is served as public; a path equal to a page without [ is served as page.
- afterFiles: each matching rule rewrites the current path (step "afterFiles <source> -> <new path>"). After each rewrite, if the path is now served by the filesystem or a dynamic route, stop there.
- Dynamic routes: pages with [param] (one segment) or [...param] (one or more segments); prefer pages whose earlier segments are static.
- fallback: like afterFiles, with steps "fallback ...".
- A path starting with http:// or https:// after any rewrite phase is served as external.
- Otherwise the result is a 404 for the current path.
Return { type, status, destination, headers, steps }: type is "redirect", "page" (destination = the page pattern), "public", "external" (all 200, except redirects) or "404" (status 404).