Skip to content

Next.js β€” React Framework Guide

Last reviewed: 2026-09-17

Next.js is a React meta-framework created by Vercel that provides server-side rendering (SSR), static site generation (SSG), API routes, file-based routing, and full-stack capabilities out of the box. It is the recommended framework for production React applications.


Overview

Next.js extends React with: - File-based routing β€” files in app/ or pages/ automatically become routes - App Router (Next.js 13+) β€” new routing paradigm built on React Server Components - Rendering strategies β€” SSR, SSG, ISR (Incremental Static Regeneration) - API routes / Route Handlers β€” backend endpoints alongside the frontend - Middleware β€” edge-level request interception - Image optimization β€” built-in <Image> component - Font optimization β€” next/font for self-hosted Google Fonts - Turbopack β€” Rust-based bundler (faster builds)


Topics Covered

  • App Router project structure and file-based routing
  • Server Components vs Client Components
  • Data fetching, caching and revalidation
  • Route Handlers and Server Actions
  • Rendering strategies for production (SSR / SSG / ISR)
  • Middleware, images, fonts and build tooling

App Router (Next.js 13+)

app/
β”œβ”€β”€ layout.tsx          # Root layout (wraps all pages)
β”œβ”€β”€ page.tsx            # Home page "/"
β”œβ”€β”€ about/
β”‚   └── page.tsx        # /about
β”œβ”€β”€ blog/
β”‚   β”œβ”€β”€ layout.tsx      # Blog section layout
β”‚   β”œβ”€β”€ page.tsx        # /blog (list)
β”‚   └── [slug]/
β”‚       └── page.tsx    # /blog/:slug (dynamic route)
└── api/
    └── hello/
        └── route.ts    # API endpoint /api/hello

Server vs Client Components

// Server Component (default in App Router)
// Can be async, direct DB access, no hooks
async function BlogList() {
  const posts = await db.posts.findMany();
  return <ul>{posts.map(p => <li key={p.id}>{p.title}</li>)}</ul>;
}

// Client Component β€” add "use client" directive
// When you need interactivity, hooks, browser APIs
"use client";
function LikeButton() {
  const [liked, setLiked] = useState(false);
  return <button onClick={() => setLiked(!liked)}>β™₯</button>;
}

Data Fetching (App Router)

// Fetch at request time (dynamic)
async function Page() {
  const data = await fetch('https://api.example.com/data');
  return <div>{/* render data */}</div>;
}
  • Static by default β€” fetch() defaults to cache: 'force-cache'
  • Dynamic β€” cache: 'no-store' or next: { revalidate: 60 } for ISR
  • Server Components fetch directly β€” no useEffect needed for data

Route Handlers

File-based HTTP endpoints live in app/**/route.ts and export one function per verb:

// app/api/orders/route.ts
import { NextResponse } from "next/server";

export async function GET() {
  const orders = await db.orders.findMany();
  return NextResponse.json(orders);
}

export async function POST(request: Request) {
  const body = await request.json();
  const created = await db.orders.create({ data: body });
  return NextResponse.json(created, { status: 201 });
}

Server Actions

Mutations can be written as async functions marked "use server", called directly from a form β€” no manual fetch or API route:

async function createTodo(formData: FormData) {
  "use server";
  await db.todos.create({ data: { text: String(formData.get("text")) } });
}

export default function TodoForm() {
  return (
    <form action={createTodo}>
      <input name="text" />
      <button type="submit">Add</button>
    </form>
  );
}

Key Features

Feature Description
SSR Render on each request (dynamic content)
SSG Pre-build at build time (fast, cached)
ISR Re-generate pages periodically (stale-while-revalidate)
Middleware Edge functions for redirects, auth, i18n
Route Handlers Full HTTP API endpoints in app/api/
Server Actions Form submissions without manual API routes

Common Commands

npx create-next-app@latest my-app   # scaffold a project
npm run dev                          # dev server with fast refresh
npm run build                        # production build
npm run start                        # serve the production build
npx next lint                        # ESLint via Next
npx next build --turbo               # build with Turbopack

Resources


To-do

Status: incomplete. Still to write:

  • Write the middleware section promised in Topics Covered (middleware.ts with config.matcher, redirect/auth/i18n use cases) β€” middleware currently has one row in the feature table.
  • Document image optimization with the <Image> component β€” it is named once in the Overview bullet list and never shown.
  • Document font optimization with next/font β€” named once in the Overview bullet list and never shown.