Use when adding new error messages to React, or seeing "unknown error code" warnings.
npx skills add soilmass/vibe-coding-plugin --skill "nextjs-routing"
Install specific skill from multi-skill repository
# Description
>
# SKILL.md
name: nextjs-routing
description: >
Next.js 15 App Router routing — file conventions, async params/searchParams, parallel routes, intercepting routes, route groups, next/form
allowed-tools: Read, Grep, Glob
Next.js Routing
Purpose
Next.js 15 App Router file-based routing. Covers route conventions, async params,
parallel/intercepting routes, and route groups. The ONE skill for URL-to-component mapping.
When to Use
- Creating new pages or route segments
- Setting up layouts, loading, and error boundaries
- Using parallel routes or intercepting routes
- Accessing route params or search params
When NOT to Use
- Middleware-level redirects →
nextjs-middleware - API endpoints →
api-routes - Data fetching within routes →
nextjs-data
Pattern
File conventions
src/app/
├── page.tsx # / route
├── layout.tsx # Root layout (required)
├── loading.tsx # Loading UI (Suspense boundary)
├── error.tsx # Error boundary ("use client")
├── not-found.tsx # 404 page
├── dashboard/
│ ├── page.tsx # /dashboard
│ ├── layout.tsx # Dashboard layout
│ └── settings/
│ └── page.tsx # /dashboard/settings
├── blog/
│ └── [slug]/
│ └── page.tsx # /blog/:slug (dynamic)
├── shop/
│ └── [...slug]/
│ └── page.tsx # /shop/* (catch-all)
└── (marketing)/ # Route group (no URL segment)
├── layout.tsx
└── about/page.tsx # /about
Async params (Next.js 15 — params is a Promise)
export default async function Page({
params,
}: {
params: Promise<{ slug: string }>;
}) {
const { slug } = await params; // Must await!
return <div>{slug}</div>;
}
Async searchParams
export default async function Page({
searchParams,
}: {
searchParams: Promise<{ q?: string }>;
}) {
const { q } = await searchParams; // Must await!
return <div>Search: {q}</div>;
}
Parallel routes
src/app/dashboard/
├── layout.tsx # Renders {children}, {analytics}, {team}
├── page.tsx # Default children
├── @analytics/
│ └── page.tsx # analytics slot
└── @team/
└── page.tsx # team slot
Anti-pattern
// WRONG: destructuring params without awaiting
export default async function Page({
params: { slug },
}: {
params: { slug: string }; // Not a Promise — breaks in Next.js 15!
}) {
return <div>{slug}</div>;
}
In Next.js 15, params and searchParams are Promises. Destructuring
before awaiting causes runtime errors.
Common Mistakes
- Destructuring params/searchParams before awaiting — they're Promises
- Adding
"use client"to layout files — layouts should be Server Components - Forgetting
loading.tsx— no Suspense boundary for slow pages - Not using route groups
()for shared layouts without URL segments - Missing
not-found.tsx— default 404 is unstyled
Checklist
- [ ]
paramsandsearchParamsare awaited before use - [ ] Root
layout.tsxexists with<html>and<body> - [ ] Route groups used for organizational layout sharing
- [ ]
loading.tsxprovides Suspense boundaries - [ ] Dynamic routes use
[param]naming convention
Composes With
error-handling— error.tsx is a routing conventionreact-suspense— loading.tsx creates Suspense boundariesnextjs-middleware— middleware runs before route resolutioni18n— locale-aware routing with[locale]segmentsstate-management— URL state syncs with route params via nuqs
# Supported AI Coding Agents
This skill is compatible with the SKILL.md standard and works with all major AI coding agents:
Learn more about the SKILL.md standard and how to use these skills with your preferred AI coding agent.