Next.js Cheatsheet
Basics
Use this Next.js reference while you build software engineering projects, review code, or refresh the syntax you reach for most.
Next.js Cheatsheet for App Router
Use this Next.js cheatsheet as a dense developer reference for React teams building routed applications, API routes, SEO pages, and production deployments. Pair it with the React cheatsheet, Git cheatsheet, SQL cheatsheet, and Python cheatsheet when a full-stack workflow crosses components, version control, data, and scripts.
Project Setup
# Create a new Next.js app (latest) npx create-next-app@latest my-app cd my-app npm run dev # dev server at http://localhost:3000 npm run build # production build (also type-checks) npm start # serve production build npm run lint # ESLint
Prompts during create-next-app: TypeScript, ESLint, Tailwind, src/ directory, App Router, import alias (@/*).
Project Structure (App Router)
my-app/ ├── app/ # App Router root │ ├── layout.tsx # Root layout (required) │ ├── page.tsx # Home page / │ ├── globals.css # Global styles │ ├── about/ │ │ └── page.tsx # /about │ └── api/ │ └── hello/ │ └── route.ts # /api/hello (Route Handler) ├── components/ # Shared components ├── lib/ # Utilities, helpers ├── public/ # Static files (served at /) ├── next.config.ts # Next.js config ├── tsconfig.json └── package.json
src/directory is optional —app/can live at the root or insidesrc/.
next.config.ts
import type { NextConfig } from 'next' const config: NextConfig = { // Allowed image domains for next/image images: { remotePatterns: [ { protocol: 'https', hostname: 'example.com' }, ], }, // Expose env vars to the browser env: { CUSTOM_VAR: process.env.CUSTOM_VAR, }, // Redirect old paths async redirects() { return [ { source: '/old', destination: '/new', permanent: true }, ] }, // Rewrite paths (proxy without redirect) async rewrites() { return [ { source: '/api/:path*', destination: 'https://api.example.com/:path*' }, ] }, // Add custom HTTP response headers async headers() { return [ { source: '/(.*)', headers: [{ key: 'X-Frame-Options', value: 'DENY' }], }, ] }, } export default config
TypeScript Path Alias
Configured in tsconfig.json by default when using @/*:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./*"]
}
}
}// Use anywhere import { Button } from '@/components/button' import { db } from '@/lib/db'
package.json Scripts
| Script | What it does |
|---|---|
npm run dev | Dev server with Fast Refresh |
npm run build | Production build + type-check |
npm start | Serve the production build |
npm run lint | Run ESLint |
Absolute Must-Knows
- App Router (
app/) is the default since Next.js 13; Pages Router (pages/) still works but is legacy. - Every file inside
app/is a Server Component by default. Add'use client'to opt into client-side rendering. - In Next.js 16, request interception lives in Proxy (
proxy.ts), formerly Middleware (middleware.tsstill works in Next ≤15 code). next buildtype-checks the whole project — TypeScript errors fail the production build.- Static files in
public/are served as-is:public/logo.png→/logo.png. - Next.js ships zero-config: bundling, code-splitting, image optimization, and routing all work out of the box.
Key Conventions
| File | Purpose |
|---|---|
app/layout.tsx | Wraps all pages; must export <html> + <body> at root |
app/page.tsx | Route segment UI (/) |
app/loading.tsx | Suspense fallback for a segment |
app/error.tsx | Error boundary for a segment ('use client') |
app/not-found.tsx | 404 UI |
app/template.tsx | Like layout but re-mounts on navigation |
app/route.ts | API route handler (no JSX) |
proxy.ts | Runs before matching requests; use when request data is needed for redirects, rewrites, or headers |
Turbopack
In Next 16, Turbopack is the default bundler for both next dev and next build — no flag needed. Opt back into webpack with --webpack.
In Next 15, opt in per command (note the -- so npm forwards the flag):
npm run dev -- --turbopack
Or set it in package.json:
{ "scripts": { "dev": "next dev --turbopack" } }Scripts — next/script
Load third-party scripts without blocking rendering:
import Script from 'next/script' export default function RootLayout({ children }: { children: React.ReactNode }) { return ( <html lang="en"> <body> {children} <Script src="https://example.com/analytics.js" strategy="afterInteractive" /> </body> </html> ) }
| Strategy | When it loads |
|---|---|
beforeInteractive | Before any Next.js code / hydration (root layout only) |
afterInteractive | After hydration (default) |
lazyOnload | During browser idle time |
worker | In a web worker via Partytown (experimental) |
Inline scripts need an id; load callbacks require a Client Component:
'use client' import Script from 'next/script' <Script id="init" strategy="afterInteractive"> {`window.dataLayer = window.dataLayer || []`} </Script> <Script src="https://widget.example.com/embed.js" onLoad={() => console.log('loaded')} onError={(e) => console.error(e)} />
For Google Analytics / Tag Manager / YouTube / Maps, prefer the official wrappers:
import { GoogleAnalytics } from '@next/third-parties/google' <GoogleAnalytics gaId="G-XXXXXXX" />