| | |

Next.js 29 ▲ Cheatsheet

⏱️ Estimated read: 5 min | |

This cheatsheet covers the App Router (the canonical routing model), core file conventions, data fetching and caching APIs, and the breaking changes introduced in Next.js 16. It reflects the current stable documentation.


File Conventions (App Router)

Every directory under app/ is a route segment. Each segment can carry these special files :

FilePurposeNotes
page.tsxRoute UIRenders inside the nearest layout
layout.tsxShared UI wrapperRoot layout must contain <html> and <body>
loading.tsxSuspense fallbackAutomatic loading state for the segment
error.tsxError boundaryMust be a Client Component ('use client')
not-found.tsx404 UITriggered by notFound()
route.tsAPI endpointReplaces pages/api/*
template.tsxRe-rendered layoutUnlike layout, re-mounts on navigation
default.tsxParallel route fallbackRequired for parallel routes in v16

Core Directives

DirectiveWherePurpose
'use client'Top of fileMarks a Client Component (hydrates in browser)
'use server'Top of file or functionMarks a Server Action (callable from client)
'use cache'Top of async function/componentCaches the result (Cache Components)

Routing & Navigation

TaskAPIImport
Programmatic navigationrouter.push('/path')next/navigation
Read pathnameusePathname()next/navigation
Read search paramsuseSearchParams()next/navigation
Read route params (Server)const { id } = await paramsProps (async in v15+)
Read route params (Client)useParams()next/navigation
Redirectredirect('/login')next/navigation
Not foundnotFound()next/navigation

Dynamic segments: [slug], catch-all [...slug], optional catch-all [[...slug]] .


Data Fetching & Caching

fetch caching defaults (Next.js 15+):

PatternCodeBehavior
Staticfetch(url, { cache: 'force-cache' })Cached at build
Revalidatedfetch(url, { next: { revalidate: 3600 } })Cached, revalidated every hour
Dynamicfetch(url, { cache: 'no-store' })Every request
Default (v15+)fetch(url)Uncached

Route segment config:

export const dynamic = 'force-dynamic';   // Always dynamic
export const revalidate = 3600;           // ISR: revalidate every hour

Cache Components ('use cache'):

async function BlogPost() {
  'use cache';
  cacheLife('hours');        // Built-in profile
  cacheTag('posts');         // Tag for invalidation
  const post = await db.post.findFirst();
  return <article>{post.title}</article>;
}

Caching APIs (Next.js 16)

APIWhereBehavior
revalidateTag(tag, profile)AnywhereStale-while-revalidate; requires 2nd arg in v16
updateTag(tag)Server Actions onlyRead-your-writes; immediate refresh
refresh()Server Actions onlyRefreshes uncached data only
cacheLife(profile)Inside 'use cache'Sets cache duration ('hours', 'days', 'max')
cacheTag(tag)Inside 'use cache'Tags cached content for invalidation
// v16: second argument required
revalidateTag('posts', 'max');        // ✅
revalidateTag('posts');                // ❌ Deprecated, TypeScript error

// Immediate refresh in Server Action
'use server';
import { updateTag } from 'next/cache';
await db.users.update(id, data);
updateTag(`user-${id}`);

Proxy (Formerly Middleware)

In Next.js 16, middleware.ts was renamed to proxy.ts .

AspectDetail
File nameproxy.ts (project root or src/)
Exportexport function proxy() (named or default)
RuntimeNode.js only (Edge not supported)
Use caseOptimistic redirects, header modification
Not forAuthoritative auth checks or slow data fetching
// proxy.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export function proxy(request: NextRequest) {
  const token = request.cookies.get('session')?.value;
  if (!token && request.nextUrl.pathname.startsWith('/dashboard')) {
    return NextResponse.redirect(new URL('/login', request.url));
  }
  return NextResponse.next();
}

export const config = {
  matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
};

Server Actions

// app/actions.ts
'use server';

export async function updateProfile(formData: FormData) {
  const session = await getSession();
  if (!session) throw new Error('Unauthorized');  // Always validate

  const name = formData.get('name') as string;
  await db.user.update({ where: { id: session.user.id }, data: { name } });

  revalidateTag('profile', 'max');  // v16: second arg required
}

Key rule: Server Actions are public endpoints. Always re-validate authentication at the start of every action.


Breaking Changes (v15 → v16)

ChangeOldNew
params type{ id: string }Promise<{ id: string }> (must await)
revalidateTagrevalidateTag('tag')revalidateTag('tag', 'max')
Middleware filemiddleware.tsproxy.ts
TurbopackOpt-in (--turbopack)Default bundler
AMPSupportedRemoved
next lintAvailableRemoved; use ESLint directly
Node.js18+20.9+
TypeScript4.x5.1+

Version Requirements (Next.js 16)

DependencyMinimum
Node.js20.9.0
TypeScript5.1.0
React19.2
Chrome / Edge111+
Safari16.4+

Common Patterns

PatternImplementation
Protected pageconst session = await getSession(); if (!session) redirect('/login')
Protected actionconst session = await getSession(); if (!session) throw new Error('Unauthorized')
Lazy-load heavy componentconst Chart = dynamic(() => import('./Chart'), { ssr: false })
Image with no CLS<Image src="/hero.jpg" width={1200} height={600} alt="Hero" />
Font with no CLSconst inter = Inter({ subsets: ['latin'], display: 'swap' })
Metadataexport const metadata: Metadata = { title: 'Page' }
Dynamic metadataexport async function generateMetadata({ params }) { ... }

Quick Commands

# Create new project
npx create-next-app@latest

# Upgrade with guidance
npx next upgrade

# Build (Turbopack default in v16)
next build

# Build with Webpack (opt-out)
next build --webpack

# App Router migration codemod
npx @next/codemod@latest app-router-migration ./pages

Summary

AreaKey Takeaway
RoutingFile-system based; page.tsx renders, layout.tsx wraps
ComponentsServer by default; 'use client' for interactivity
Data fetchingColocated in async Server Components; fetch uncached by default since v15
Caching'use cache' + cacheLife + cacheTag; revalidateTag requires profile arg in v16
Server ActionsPublic endpoints; always re-validate auth
MiddlewareRenamed to proxy.ts in v16; optimistic checks only
BundleTurbopack is default in v16

Remember: The App Router is not a collection of APIs to memorize—it is a mental model shift. Server Components render on the server and ship zero JS. Client Components hydrate. Server Actions are endpoints. The file system is the router. The caching APIs exist to make the default (dynamic) faster without sacrificing correctness. Learn the boundary rules, and the APIs follow naturally.

Was this helpful?


Stop using slow, ad-bloated tool sites! 🤮

🔎 Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)

⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free

🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!