Skip
Arish's avatar

34. Next.js Introduction


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?

FeatureCreate React AppNext.js
SSR/SSG
File-based routing
API routes
Image optimization
Built-in CSSLimited
SEOManualBuilt-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? Yes

Project 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/settings

Server 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 UsersPage

Client 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/>
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!