▲ Next.js — Zero to Hero
The React framework for production — SSR, SSG, API routes and more
▲ What is Next.js?
Next.js is a React framework by Vercel that adds server-side rendering, file-based routing, API routes, and much more out of the box.
📁 File Routing
Create a file = create a route. No config needed.
🖥 SSR & SSG
Server-side rendering and static generation built in.
🔌 API Routes
Build backend endpoints in the same project.
⚡ Performance
Automatic code splitting, image optimization, caching.
⚙️ Setup
# Create new Next.js app npx create-next-app@latest my-app cd my-app npm run dev # → http://localhost:3000
Project structure:
my-app/ ├── app/ # App Router (Next 13+) │ ├── layout.js # Root layout │ ├── page.js # Homepage / │ └── about/ │ └── page.js # /about route ├── public/ # Static assets └── next.config.js # Config
📁 File-Based Routing
| File path | URL |
|---|---|
app/page.js | / |
app/about/page.js | /about |
app/blog/[slug]/page.js | /blog/my-post |
app/shop/[...path]/page.js | /shop/a/b/c |
app/api/users/route.js | GET /api/users |
📄 Pages & Layouts
// app/layout.js — wraps all pages export default function RootLayout({ children }) { return ( <html lang="en"> <body> <Navbar /> {children} <Footer /> </body> </html> ); } // app/page.js — homepage export default function Home() { return <h1>Welcome to Next.js!</h1>; }
🖥 Server Components
By default, all components in the App Router are Server Components. They run on the server — no JS sent to the browser.
// app/users/page.js — Server Component (default) async function getUsers() { const res = await fetch('https://api.example.com/users', { next: { revalidate: 60 } // ISR: revalidate every 60s }); return res.json(); } export default async function UsersPage() { const users = await getUsers(); return ( <ul> {users.map(u => <li key={u.id}>{u.name}</li>)} </ul> ); }
💻 Client Components
Add 'use client' at the top when you need interactivity, state, or browser APIs.
'use client'; import { useState } from 'react'; export default function Counter() { const [count, setCount] = useState(0); return <button onClick={() => setCount(c => c+1)}>Count: {count}</button>; }
💡 Keep Server Components for data fetching. Use Client Components only at the leaves of the tree where interactivity is needed.
📡 Data Fetching
| Strategy | Code | When to use |
|---|---|---|
| SSR (every request) | cache: 'no-store' | Real-time data |
| SSG (build time) | cache: 'force-cache' | Rarely changes |
| ISR (revalidate) | next: {'{'}revalidate: 60{'}'} | Periodic refresh |
// SSR — fresh on every request const res = await fetch(url, { cache: 'no-store' }); // SSG — cached at build const res = await fetch(url, { cache: 'force-cache' }); // ISR — revalidate every 60 seconds const res = await fetch(url, { next: { revalidate: 60 } });
🔌 API Routes
// app/api/users/route.js import { NextResponse } from 'next/server'; export async function GET() { const users = [{ id: 1, name: 'Alice' }]; return NextResponse.json(users); } export async function POST(request) { const body = await request.json(); // save to DB... return NextResponse.json({ success: true }, { status: 201 }); }
🔀 Dynamic Routes
// app/blog/[slug]/page.js export default function BlogPost({ params }) { return <h1>Post: {params.slug}</h1>; } // Pre-generate paths at build time export async function generateStaticParams() { const posts = await fetchAllPosts(); return posts.map(p => ({ slug: p.slug })); }
🏷 Metadata & SEO
// app/about/page.js export const metadata = { title: 'About Us | My App', description: 'Learn more about our company', openGraph: { title: 'About Us', images: ['/og-image.png'], }, }; // Dynamic metadata export async function generateMetadata({ params }) { const post = await fetchPost(params.slug); return { title: post.title }; }
🖼 Image & Font Optimization
import Image from 'next/image'; import Link from 'next/link'; import { Inter } from 'next/font/google'; const inter = Inter({ subsets: ['latin'] }); export default function Page() { return ( <div className={inter.className}> <Image src="/hero.png" alt="Hero" width={800} height={400} priority /> <Link href="/about">About</Link> </div> ); }
🛡 Middleware
// middleware.js (project root) import { NextResponse } from 'next/server'; export function middleware(request) { const token = request.cookies.get('token'); if (!token && request.nextUrl.pathname.startsWith('/dashboard')) { return NextResponse.redirect(new URL('/login', request.url)); } return NextResponse.next(); } export const config = { matcher: ['/dashboard/:path*'] };
🚀 Deployment
# Build for production npm run build # Deploy to Vercel (easiest) npm i -g vercel vercel # Or self-host with Node npm run build npm start
🎉 You now know Next.js! Explore NextAuth.js for authentication, Prisma for database, and Vercel for instant deployment.