New skills: - next-best-practices: Next.js 15+ RSC, async patterns, self-hosting (vercel-labs) - better-auth-best-practices: Official Better-Auth with Drizzle adapter (better-auth) - verification-before-completion: Evidence-based completion claims (obra/superpowers) - shadcn-ui: Component patterns with Tailwind v4 adaptation note (developer-kit) - writing-skills: TDD methodology for skill authoring (obra/superpowers) README reorganized by category with Mosaic Stack alignment section. Total: 9 skills (4 existing + 5 new). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
3.4 KiB
3.4 KiB
File Conventions
Next.js App Router uses file-based routing with special file conventions.
Project Structure
Reference: https://nextjs.org/docs/app/getting-started/project-structure
app/
├── layout.tsx # Root layout (required)
├── page.tsx # Home page (/)
├── loading.tsx # Loading UI
├── error.tsx # Error UI
├── not-found.tsx # 404 UI
├── global-error.tsx # Global error UI
├── route.ts # API endpoint
├── template.tsx # Re-rendered layout
├── default.tsx # Parallel route fallback
├── blog/
│ ├── page.tsx # /blog
│ └── [slug]/
│ └── page.tsx # /blog/:slug
└── (group)/ # Route group (no URL impact)
└── page.tsx
Special Files
| File | Purpose |
|---|---|
page.tsx |
UI for a route segment |
layout.tsx |
Shared UI for segment and children |
loading.tsx |
Loading UI (Suspense boundary) |
error.tsx |
Error UI (Error boundary) |
not-found.tsx |
404 UI |
route.ts |
API endpoint |
template.tsx |
Like layout but re-renders on navigation |
default.tsx |
Fallback for parallel routes |
Route Segments
app/
├── blog/ # Static segment: /blog
├── [slug]/ # Dynamic segment: /:slug
├── [...slug]/ # Catch-all: /a/b/c
├── [[...slug]]/ # Optional catch-all: / or /a/b/c
└── (marketing)/ # Route group (ignored in URL)
Parallel Routes
app/
├── @analytics/
│ └── page.tsx
├── @sidebar/
│ └── page.tsx
└── layout.tsx # Receives { analytics, sidebar } as props
Intercepting Routes
app/
├── feed/
│ └── page.tsx
├── @modal/
│ └── (.)photo/[id]/ # Intercepts /photo/[id] from /feed
│ └── page.tsx
└── photo/[id]/
└── page.tsx
Conventions:
(.)- same level(..)- one level up(..)(..)- two levels up(...)- from root
Private Folders
app/
├── _components/ # Private folder (not a route)
│ └── Button.tsx
└── page.tsx
Prefix with _ to exclude from routing.
Middleware / Proxy
Next.js 14-15: middleware.ts
// middleware.ts (root of project)
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
// Auth, redirects, rewrites, etc.
return NextResponse.next();
}
export const config = {
matcher: ['/dashboard/:path*', '/api/:path*'],
};
Next.js 16+: proxy.ts
Renamed for clarity - same capabilities, different names:
// proxy.ts (root of project)
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function proxy(request: NextRequest) {
// Same logic as middleware
return NextResponse.next();
}
export const proxyConfig = {
matcher: ['/dashboard/:path*', '/api/:path*'],
};
| Version | File | Export | Config |
|---|---|---|---|
| v14-15 | middleware.ts |
middleware() |
config |
| v16+ | proxy.ts |
proxy() |
proxyConfig |
Migration: Run npx @next/codemod@latest upgrade to auto-rename.
File Conventions Reference
Reference: https://nextjs.org/docs/app/api-reference/file-conventions