diff --git a/docs/advanced-features/middleware.md b/docs/advanced-features/middleware.md index 96e4b9f13ad2266..e7f22f7776f7eac 100644 --- a/docs/advanced-features/middleware.md +++ b/docs/advanced-features/middleware.md @@ -9,6 +9,7 @@ description: Learn how to use Middleware to run code before a request is complet | Version | Changes | | --------- | ------------------------------------------------------------------------------------------ | +| `v13.1.0` | Advanced Middleware flags added | | `v13.0.0` | Middleware can modify request headers, response headers, and send responses | | `v12.2.0` | Middleware is stable | | `v12.0.9` | Enforce absolute URLs in Edge Runtime ([PR](https://github.com/vercel/next.js/pull/33410)) | @@ -257,6 +258,66 @@ export function middleware(request: NextRequest) { } ``` +## Advanced Middleware Flags + +In `v13.1` of Next.js two additional flags were introduced for middleware, `skipMiddlewareUrlNormalize` and `skipTrailingSlashRedirect` to handle advanced use cases. + +`skipTrailingSlashRedirect` allows disabling Next.js default redirects for adding or removing trailing slashes allowing custom handling inside middleware which can allow maintaining the trailing slash for some paths but not others allowing easier incremental migrations. + +```js +// next.config.js +module.exports = { + skipTrailingSlashRedirect: true, +} +``` + +```js +// middleware.js + +const legacyPrefixes = ['/docs', '/blog'] + +export default async function middleware(req) { + const { pathname } = req.nextUrl + + if (legacyPrefixes.some((prefix) => pathname.startsWith(prefix))) { + return NextResponse.next() + } + + // apply trailing slash handling + if ( + !pathname.endsWith('/') && + !pathname.match(/((?!\.well-known(?:\/.*)?)(?:[^/]+\/)*[^/]+\.\w+)/) + ) { + req.nextUrl.pathname += '/' + return NextResponse.redirect(req.nextUrl) + } +} +``` + +`skipMiddlewareUrlNormalize` allows disabling the URL normalizing Next.js does to make handling direct visits and client-transitions the same. There are some advanced cases where you need full control using the original URL which this unlocks. + +```js +// next.config.js + +module.exports = { + skipMiddlewareUrlNormalize: true, +} +``` + +```js +// middleware.js + +export default async function middleware(req) { + const { pathname } = req.nextUrl + + // GET /_next/data/build-id/hello.json + + console.log(pathname) + // with the flag this now /_next/data/build-id/hello.json + // without the flag this would be normalized to /hello +} +``` + ## Related