Next.js Introduction
Next.js is the React framework for production, offering server-side rendering, static generation, and a great developer experience.
Why Next.js?
| Feature | Create React App | Next.js |
|---|---|---|
| SSR/SSG | ❌ | ✅ |
| File-based routing | ❌ | ✅ |
| API routes | ❌ | ✅ |
| Image optimization | ❌ | ✅ |
| Built-in CSS | Limited | ✅ |
| SEO | Manual | Built-in |
Installation
bash
1npx create-next-app@latest my-app
2
3# Options
4✔ TypeScript? Yes
5✔ ESLint? Yes
6✔ Tailwind CSS? Yes
7✔ `src/` directory? Yes
8✔ App Router? YesProject Structure
my-app/
├── src/
│ └── app/
│ ├── layout.tsx # Root layout
│ ├── page.tsx # Home page (/)
│ ├── globals.css # Global styles
│ ├── about/
│ │ └── page.tsx # /about
│ └── blog/
│ ├── page.tsx # /blog
│ └── [slug]/
│ └── page.tsx # /blog/:slug
├── public/ # Static files
├── next.config.js # Configuration
└── package.json
Routing (App Router)
Basic Pages
tsx
1// app/page.tsx - Home (/)
2export default function Home() {
3 return <h1>Welcome Home</h1>
4}
5
6// app/about/page.tsx - About (/about)
7export default function About() {
8 return <h1>About Us</h1>
9}Dynamic Routes
tsx
1// app/blog/[slug]/page.tsx
2interface Props {
3 params: { slug: string }
4}
5
6export default function BlogPost({ params }: Props) {
7 return <h1>Blog: {params.slug}</h1>
8}
9
10// Generates /blog/hello-world, /blog/my-post, etc.Nested Routes
tsx
1// app/dashboard/layout.tsx
2export default function DashboardLayout({
3 children,
4}: {
5 children: React.ReactNode
6}) {
7 return (
8 <div className="dashboard">
9 <Sidebar />
10 <main>{children}</main>
11 </div>
12 )
13}
14
15// app/dashboard/page.tsx - /dashboard
16// app/dashboard/settings/page.tsx - /dashboard/settingsServer vs Client Components
Server Components (default)
tsx
1// app/users/page.tsx - Server Component
2async function UsersPage() {
3 // Fetch data on server
4 const users = await fetch('https://api.example.com/users').then(r => r.json())
5
6 return (
7 <ul>
8 {users.map(user => (
9 <li key={user.id}>{user.name}</li>
10 ))}
11 </ul>
12 )
13}
14
15export default UsersPageClient Components
tsx
1'use client' // Mark as client component
2
3import { useState } from 'react'
4
5export default function Counter() {
6 const [count, setCount] = useState(0)
7
8 return (
9 <button onClick={() => setCount(count + 1)}>
10 Count: {count}
11 </button>
12 )
13}Data Fetching
Server Components
tsx
1// Direct async/await in component
2async function ProductPage({ params }: { params: { id: string } }) {
3 const product = await fetch(`/api/products/${params.id}`).then(r => r.json())
4
5 return <ProductDetails product={product} />
6}
7
8// With caching options
9const data = await fetch('...', {
10 cache: 'force-cache', // Default - cache forever
11 // cache: 'no-store', // Always fresh
12 // next: { revalidate: 60 } // Revalidate every 60s
13})Static Generation
tsx
1// Generate static pages at build time
2export async function generateStaticParams() {
3 const posts = await getPosts()
4
5 return posts.map(post => ({
6 slug: post.slug
7 }))
8}
9
10export default async function BlogPost({ params }: { params: { slug: string } }) {
11 const post = await getPost(params.slug)
12 return <Article post={post} />
13}API Routes
tsx
1// app/api/users/route.ts
2import { NextResponse } from 'next/server'
3
4export async function GET() {
5 const users = await db.users.findMany()
6 return NextResponse.json(users)
7}
8
9export async function POST(request: Request) {
10 const body = await request.json()
11 const user = await db.users.create({ data: body })
12 return NextResponse.json(user, { status: 201 })
13}Metadata and SEO
tsx
1// app/layout.tsx
2import { Metadata } from 'next'
3
4export const metadata: Metadata = {
5 title: 'My App',
6 description: 'My awesome app description',
7 openGraph: {
8 title: 'My App',
9 description: 'My awesome app',
10 images: ['/og-image.png']
11 }
12}
13
14// Dynamic metadata
15export async function generateMetadata({ params }): Promise<Metadata> {
16 const post = await getPost(params.slug)
17 return {
18 title: post.title,
19 description: post.excerpt
20 }
21}Image Optimization
tsx
1import Image from 'next/image'
2
3function Avatar() {
4 return (
5 <Image
6 src="/avatar.jpg"
7 alt="Avatar"
8 width={100}
9 height={100}
10 priority // Load immediately
11 />
12 )
13}
14
15// External images (add domain to next.config.js)
16<Image
17 src="https://example.com/photo.jpg"
18 alt="Photo"
19 width={800}
20 height={600}
21/>Navigation
tsx
1import Link from 'next/link'
2import { useRouter } from 'next/navigation'
3
4function Nav() {
5 const router = useRouter()
6
7 return (
8 <nav>
9 <Link href="/">Home</Link>
10 <Link href="/about">About</Link>
11
12 <button onClick={() => router.push('/dashboard')}>
13 Go to Dashboard
14 </button>
15 </nav>
16 )
17}Next.js is the production-ready framework for React!
