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 inside src/.

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

ScriptWhat it does
npm run devDev server with Fast Refresh
npm run buildProduction build + type-check
npm startServe the production build
npm run lintRun 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.ts still works in Next ≤15 code).
  • next build type-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

FilePurpose
app/layout.tsxWraps all pages; must export <html> + <body> at root
app/page.tsxRoute segment UI (/)
app/loading.tsxSuspense fallback for a segment
app/error.tsxError boundary for a segment ('use client')
app/not-found.tsx404 UI
app/template.tsxLike layout but re-mounts on navigation
app/route.tsAPI route handler (no JSX)
proxy.tsRuns 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>
  )
}
StrategyWhen it loads
beforeInteractiveBefore any Next.js code / hydration (root layout only)
afterInteractiveAfter hydration (default)
lazyOnloadDuring browser idle time
workerIn 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" />