Test your Next.js middleware matcher before you deploy
A matcher decides which requests reach your middleware, and a small mistake either leaves a page unprotected or sends your CSS, images and API calls through an auth redirect. This Next.js middleware matcher tester shows the answer for every route at once: green when the middleware runs, grey when the route is skipped.
It doesn't guess with a generic regex tester. The matcher is compiled the way next build compiles it, with path-to-regexp 6.3.0 and the prefixes and suffixes Next.js adds, and the result was checked against Next.js's own matching function on thousands of route and pattern combinations.
How to exclude paths from Next.js middleware
The usual way to exclude paths is a negative lookahead: '/((?!api|_next/static|_next/image|favicon.ico).*)' runs the middleware on every path except the ones that start with those words. Paste it above and add your own routes to see exactly what it leaves out.
One catch surprises many developers: the lookahead checks how the path starts, not whole folder names. 'api' also excludes /apiary and /api-docs. Write 'api/' or 'api(?:/|$)' when you only mean the API folder; the tester points this out when it happens.
Why your Next.js middleware matcher is not working
Most matcher bugs come from a handful of causes. The config must be exported as export const config with literal strings, because Next.js reads it at build time; variables and template strings with ${…} are ignored. Every pattern must start with a slash, and matching is case-sensitive.
Named parameters only cover one segment: '/dashboard/:path' matches /dashboard/settings but not /dashboard/settings/billing, while '/dashboard/:path*' covers both and /dashboard itself. A plain '/about' matches /about but not /about/team. In a JavaScript string, a single backslash before a dot is dropped, so write '\\.' to match a literal dot. The tester flags each of these.
Match all routes, or only some
Leave the matcher out and middleware runs on every request, static files included. For all pages but no static assets, use a negative lookahead; for a few protected sections, list them in an array such as ['/dashboard/:path*', '/account/:path*']. Multiple matchers are checked in order, and the tester shows which one matched each route.
Ignore the public folder and static files
Files in the public folder are served from the site root, so /logo.png and /robots.txt pass through middleware unless the matcher excludes them. A common fix is to skip any path that contains a dot, as in '/((?!_next|.*\\..*).*)'. Test it with your real routes first: a page such as /blog/version-1.2 also contains a dot and would be skipped too.
Hidden routes: _next/data, .rsc and prefetches
Next.js quietly extends every matcher. Pages Router data requests (/_next/data/<build-id>/page.json) and App Router .rsc and segment prefetch requests match whenever the page matches, even if your pattern excludes _next/data. That keeps data routes protected along with their pages.
To skip prefetches, use the object form with missing: [{ type: 'header', key: 'next-router-prefetch' }]. Add the headers and cookies of a request in the options above to test has and missing conditions.
Fewer middleware calls: faster pages and lower costs
Every request that matches runs your middleware before Next.js can send a response. On a typical page that includes JavaScript chunks, images, fonts and the favicon, so a matcher that lets them through adds work to dozens of requests, and on hosts that bill per middleware or function invocation, it adds to the bill as well.
Checking the path inside the middleware with if statements doesn't avoid this, because the function still starts for every request. Excluding static files in the matcher means those requests never reach it at all. Use the tester to confirm that _next/static, images and other public files are skipped while every page that needs protection still runs.
Next.js 16: proxy.ts uses the same matcher
Next.js 16 renamed middleware.ts to proxy.ts and the exported function to proxy, and it runs on the Node.js runtime by default. The config and matcher syntax didn't change, so the Next.js proxy matcher works exactly like the middleware matcher, and this tester covers both.
basePath, i18n and the regex behind it
If your next.config sets a basePath or Pages Router i18n locales, enter them in the options and the matcher is compiled with them, just like in a build. Open the regex panel to see and copy the final regular expression Next.js uses for each pattern.
Protecting routes with a JWT? Our JWT decoder shows what's inside the token your middleware checks and when it expires. If an AI assistant edits your middleware, add the routing rules to a CLAUDE.md or Cursor rules file.
Private by design
Your config and routes never leave the page. The tester is plain code running in your browser, with no upload and no account, like all of our free developer tools that run in your browser.