Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Middleware config matcher must support '^' at beginning of source in order to have documented behavior #70096

Open
1 task done
wayne-crosby opened this issue Sep 14, 2024 · 0 comments

Comments

@wayne-crosby
Copy link

wayne-crosby commented Sep 14, 2024

Verify canary release

  • I verified that the issue exists in the latest Next.js canary release

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 23.6.0: Mon Jul 29 21:14:30 PDT 2024; root:xnu-10063.141.2~1/RELEASE_ARM64_T6000
  Available memory (MB): 32768
  Available CPU cores: 10
Binaries:
  Node: 21.7.3
  npm: 10.5.1
  Yarn: 1.22.19
  pnpm: N/A
Relevant Packages:
  next: 14.2.3 // There is a newer version (14.2.11) available, upgrade recommended! 
  eslint-config-next: 13.5.6
  react: 18.3.1
  react-dom: 18.3.1
  typescript: 5.5.4
Next.js Config:
  output: standalone
 ⚠ There is a newer version (14.2.11) available, upgrade recommended! 
   Please try the latest canary version (`npm install next@canary`) to confirm the issue still exists before creating a new issue.
   Read more - https://nextjs.org/docs/messages/opening-an-issue

Which example does this report relate to?

https://codesandbox.io/p/devbox/nervous-fire-gzd3q9?file=%2Fmiddleware.ts%3A2%2C1&workspaceId=8f05b73a-deb4-4322-876e-31d3ccb37576

What browser are you using? (if relevant)

NA

How are you deploying your application? (if relevant)

Vercel

Describe the Bug

middleware.ts
The example given in the middleware docs at: https://nextjs.org/docs/app/building-your-application/routing/middleware#matcher do not work as expected.

export const config = {
  matcher: [
    /*
     * Match all request paths except for the ones starting with:
     * - api (API routes)
     * - _next/static (static files)
     * - _next/image (image optimization files)
     * - favicon.ico, sitemap.xml, robots.txt (metadata files)
     */
    '/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)',
  ],
}

This still matches any route like /api/foo. In order to get the desired behavior, you need to start this RE with '^'.

So the correct solution config should be:

export const config = {
  matcher: [
    /*
     * Match all request paths except for the ones starting with:
     * - api (API routes)
     * - _next/static (static files)
     * - _next/image (image optimization files)
     * - favicon.ico, sitemap.xml, robots.txt (metadata files)
     */
    '^/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)',
  ],
}

However, this throws an error during build since it says the source does not start with /. Please update this check to also support '^' so the matcher have the desired behavior, and not send every request to middleware.

I'm pretty sure the fix is changing this line:

} else if (!route.source.startsWith('/')) {

It should be

} else if (!route.source.startsWith('/') && !route.source.startsWith('^')) {

Expected Behavior

All paths under /api, such as /api/foo should not match and thus not be processed by middleware.

To Reproduce

const documentedMatcher = new RegExp('/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)');
const testRoutes = ['/api', '/api/foo', '/image'];
testRoutes.forEach(route => console.log(`${route} -> ${documentedMatcher.test(route)}`));
// expected output
// /api -> false
// /api/foo -> false
// /image -> true

// actual output 
// /api -> false
// /api/foo -> true <--- not desired behavior
// /image -> true

const correctMatcher = new RegExp('^/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)');
testRoutes.forEach(route => console.log(`${route} -> ${correctMatcher.test(route)}`));
// actual output 
// /api -> false
// /api/foo -> false <--- correct behavior needs to start regex with '^' to anchor to start
// /image -> true
@wayne-crosby wayne-crosby added the examples Issue/PR related to examples label Sep 14, 2024
@wayne-crosby wayne-crosby changed the title Next-auth config matcher must support '^' at beginning of source in order to have documented behavior Middleware config matcher must support '^' at beginning of source in order to have documented behavior Sep 14, 2024
@samcx samcx removed the examples Issue/PR related to examples label Sep 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants