Skip to content

Understanding Next.js App Router Dynamic API Params

James Cross edited this page Jun 17, 2025 · 1 revision

✅ What This Covers

A reusable note explaining why dynamic params like [slug] break in app/api/, the root cause, the fix, and a copy-pastable pattern.


⚡️ The Problem

Error:

Route "/api/[slug]" used `params.slug`. `params` should be awaited before using its properties.

When this happens:

  • You create a dynamic API route in app/api/:
    src/app/api/service-providers/[slug]/route.ts
    
  • You write:
    export async function GET(req: Request, { params }: { params: { slug: string } }) {
      const { slug } = params;
      // ...
    }
  • You expect params like in page.tsx.

Result:

  • Next.js App Router does NOT pass params to API handlers yet.

✅ Root Cause

  • app/route.ts is a pure serverless function.
  • It gets only Request.
  • No context or params injection for dynamic segments.
  • This is by design (still evolving).
    See Next.js Dynamic API Routes docs.

✅ How to Fix It

👉 Always parse the param manually:

export async function GET(req: Request) {
  const url = new URL(req.url);
  const parts = url.pathname.split('/');
  const slug = parts[parts.length - 1]; // Last segment
  // Use slug...
}

✔️ Works for [slug], [id], etc.


✅ Copy-Paste Helper

function getLastPathSegment(url: string): string {
  const u = new URL(url);
  const segments = u.pathname.split('/');
  return segments[segments.length - 1];
}

// Usage
const slug = getLastPathSegment(req.url);

🧩 Quick Summary

Context params available?
app/page.tsx ✅ Yes
app/api/[slug]/route.ts ❌ No — parse manually

✅ When to Use This

  • If you see: params is undefined or should be awaited in dynamic API.
  • If migrating old pages/api/[slug].ts to app/api/.
  • Always for App Router dynamic APIs.

🗂️ One-Liner

In App Router dynamic API routes, params do NOT auto-inject — manually parse from the URL.