Bird
Raised Fist0
NextJSframework~8 mins

Matching paths with config in NextJS - Performance & Optimization

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Performance: Matching paths with config
MEDIUM IMPACT
This affects how quickly Next.js can resolve routes and serve pages, impacting initial load and navigation speed.
Defining route matching rules for dynamic paths
NextJS
const routes = [
  { path: '/posts/[id]', page: 'PostPage' },
  { path: '/posts/[slug]', page: 'PostSlugPage' }
];

function matchRoute(path) {
  for (const route of routes) {
    if (path.startsWith(route.path.replace('[id]', '')) || path.startsWith(route.path.replace('[slug]', ''))) {
      return route.page;
    }
  }
  return 'CatchAllPage';
}
Uses simple string prefix checks instead of regex, reducing CPU cost and speeding up route matching.
📈 Performance GainSingle string checks per navigation, reducing blocking time to under 1ms.
Defining route matching rules for dynamic paths
NextJS
const routes = [
  { path: '/posts/:id(\\d+)', page: 'PostPage' },
  { path: '/posts/:slug([a-z-]+)', page: 'PostSlugPage' },
  { path: '/posts/:any*', page: 'CatchAllPage' }
];

function matchRoute(path) {
  for (const route of routes) {
    const regex = new RegExp('^' + route.path.replace(/:[^/]+/g, '[^/]+') + '$');
    if (regex.test(path)) return route.page;
  }
  return null;
}
Using complex regex and multiple overlapping patterns causes slow matching and multiple regex compilations on each navigation.
📉 Performance CostTriggers multiple regex compilations and tests per navigation, blocking rendering for 10-20ms on slow devices.
Performance Comparison
PatternDOM OperationsReflowsPaint CostVerdict
Complex regex matching for paths00Blocks rendering 10-20ms[X] Bad
Simple string prefix matching00Blocks rendering <1ms[OK] Good
Rendering Pipeline
Path matching runs during route resolution before rendering. Complex regex slows down the Style Calculation and Layout phases by delaying content availability.
Route Resolution
Style Calculation
Layout
⚠️ BottleneckRoute Resolution with regex matching
Core Web Vital Affected
LCP
This affects how quickly Next.js can resolve routes and serve pages, impacting initial load and navigation speed.
Optimization Tips
1Avoid complex regex in path matching to reduce CPU blocking.
2Use simple string matching or precompiled patterns for faster route resolution.
3Test route matching performance with DevTools Performance panel.
Performance Quiz - 3 Questions
Test your performance knowledge
What is the main performance issue with using complex regex for matching paths in Next.js config?
AIt causes multiple regex compilations and slows route resolution.
BIt increases DOM node count.
CIt triggers layout thrashing.
DIt blocks network requests.
DevTools: Performance
How to check: Record a profile while navigating routes. Look for long tasks during route resolution and check for regex execution time.
What to look for: Long scripting tasks before paint indicate slow path matching. Short scripting tasks show efficient matching.

Practice

(1/5)
1. In Next.js config, what does a path matcher do?
easy
A. It changes the page layout globally for all routes.
B. It automatically generates API routes from files.
C. It tells Next.js which URLs should use special rules or middleware.
D. It disables JavaScript on matched pages.

Solution

  1. Step 1: Understand the purpose of path matchers

    Path matchers specify which URLs get special handling like middleware or redirects.
  2. Step 2: Compare options

    Only It tells Next.js which URLs should use special rules or middleware. correctly describes this behavior; others describe unrelated features.
  3. Final Answer:

    It tells Next.js which URLs should use special rules or middleware. -> Option C
  4. Quick Check:

    Path matcher = special rules for URLs [OK]
Hint: Matchers select URLs for special handling in config [OK]
Common Mistakes:
  • Thinking matchers change layout globally
  • Confusing matchers with API route generation
  • Assuming matchers disable JavaScript
2. Which of the following is the correct syntax to match the exact path /dashboard in Next.js config?
easy
A. "/dashboard"
B. "/dashboard/*"
C. "dashboard"
D. "/dashboard?"

Solution

  1. Step 1: Identify exact path syntax

    Exact path matchers use the full path string without wildcards or extra characters.
  2. Step 2: Evaluate options

    "/dashboard" matches exactly "/dashboard". "/dashboard/*" includes a wildcard, C misses the leading slash, D uses an invalid character.
  3. Final Answer:

    "/dashboard" -> Option A
  4. Quick Check:

    Exact path = "/dashboard" [OK]
Hint: Exact paths need full string with leading slash, no wildcards [OK]
Common Mistakes:
  • Adding wildcards for exact matches
  • Omitting the leading slash
  • Using query-like characters in path
3. Given this Next.js config snippet:
{ matchers: ["/blog/:slug"] }

Which URL will match this pattern?
medium
A. /blog/nextjs-routing
B. /blog
C. /blog/nextjs/routing
D. /blog/

Solution

  1. Step 1: Understand dynamic segment ":slug"

    "/blog/:slug" matches paths with one segment after "/blog/", like "/blog/anything".
  2. Step 2: Check each URL

    /blog/nextjs-routing has one segment after "/blog/" so it matches. B and D lack the segment. C has two segments after "/blog/", so no match.
  3. Final Answer:

    /blog/nextjs-routing -> Option A
  4. Quick Check:

    Dynamic segment matches one path part [OK]
Hint: Dynamic :param matches one segment after base path [OK]
Common Mistakes:
  • Assuming missing segment matches
  • Thinking multiple segments match one param
  • Confusing trailing slash with segment
4. You wrote this matcher in Next.js config:
matchers: ["/profile/:id"]

But the middleware does not run on /profile. Why?
medium
A. Because "/profile" matches but middleware is disabled globally.
B. Because "/profile" lacks the required dynamic segment ":id".
C. Because middleware only runs on API routes, not pages.
D. Because the matcher syntax is invalid and causes an error.

Solution

  1. Step 1: Analyze matcher requirement

    "/profile/:id" requires a segment after "/profile/" to match.
  2. Step 2: Check why "/profile" does not match

    "/profile" has no segment after it, so it does not match the pattern, so middleware won't run.
  3. Final Answer:

    Because "/profile" lacks the required dynamic segment ":id". -> Option B
  4. Quick Check:

    Missing dynamic segment means no match [OK]
Hint: Dynamic segments must be present in URL to match [OK]
Common Mistakes:
  • Thinking matcher syntax is invalid
  • Assuming middleware runs on all pages
  • Believing global middleware disables matching
5. You want to apply middleware only to all blog posts and their comments paths like /blog/post-1 and /blog/post-1/comments. Which matcher config is correct?
hard
A. ["/blog/:postId", "/blog/:postId/comments"]
B. ["/blog/:postId*"]
C. ["/blog/:postId", "/blog/:postId/comments/*"]
D. ["/blog/:postId", "/blog/:postId/*"]

Solution

  1. Step 1: Understand matching blog posts and comments

    We want to match "/blog/:postId" exactly and also any deeper paths like "/blog/:postId/comments".
  2. Step 2: Evaluate options

    ["/blog/:postId", "/blog/:postId/*"] uses "/blog/:postId" for posts and "/blog/:postId/*" to match any sub-paths like comments. ["/blog/:postId", "/blog/:postId/comments"] misses sub-path wildcard, B uses invalid syntax, D misses direct post path.
  3. Final Answer:

    ["/blog/:postId", "/blog/:postId/*"] -> Option D
  4. Quick Check:

    Use base path plus wildcard for sub-paths [OK]
Hint: Use base dynamic path plus wildcard for nested routes [OK]
Common Mistakes:
  • Using invalid wildcard syntax
  • Missing base path matcher
  • Not including wildcard for sub-paths