What is Next.js?
Next.js is a full-stack React framework that gives you building blocks to create web applications. It handles the tooling and configuration needed for React, and provides additional structure, features, and optimizations for your application.
🎯 Key Benefits
⚡ Performance
- Automatic code splitting
- Image optimization
- Font optimization
- Script optimization
🔍 SEO
- Server-side rendering
- Static site generation
- Meta tag management
- Sitemap generation
🛠️ Developer Experience
- Zero configuration
- Fast refresh
- Built-in CSS support
- TypeScript support
🌐 Full-stack
- API routes
- Middleware
- Database integration
- Authentication
React vs Next.js
📱 Single Page Application
- Rendering: Client-side only
- Initial Load: Shows blank page until JS loads
- SEO: Limited without additional setup
- Routing: Requires React Router
- Performance: Depends on bundle size
✅ Best For:
- Interactive dashboards
- Web applications
- Admin panels
- Complex user interfaces
🌐 Multiple Rendering Options
- Rendering: SSR, SSG, or Client-side
- Initial Load: Shows content immediately
- SEO: Excellent out of the box
- Routing: File-based routing built-in
- Performance: Optimized by default
✅ Best For:
- Marketing websites
- E-commerce sites
- Blogs and documentation
- Full-stack applications
Getting Started with Next.js
🚀 Creating a Next.js App
# Create a new Next.js app
npx create-next-app@latest my-app
# With TypeScript
npx create-next-app@latest my-app --typescript
# With Tailwind CSS
npx create-next-app@latest my-app --tailwind
# Navigate to project
cd my-app
# Start development server
npm run dev
📁 Project Structure
my-app/
├── pages/ # File-based routing
│ ├── index.js # Home page (/)
│ ├── about.js # About page (/about)
│ └── api/ # API routes
│ └── hello.js # API endpoint (/api/hello)
├── public/ # Static files
│ ├── favicon.ico
│ └── images/
├── styles/ # CSS files
│ ├── globals.css
│ └── Home.module.css
├── components/ # Reusable components
├── lib/ # Utility functions
├── next.config.js # Next.js configuration
└── package.json
File-based Routing
Next.js uses the file system for routing. Pages are associated with routes based on their file names.
🗂️ Routing Examples
pages/
├── index.js → /
├── about.js → /about
├── contact.js → /contact
├── blog/
│ ├── index.js → /blog
│ ├── [slug].js → /blog/my-post
│ └── [year]/
│ └── [month].js → /blog/2024/january
├── products/
│ ├── [id].js → /products/123
│ └── [...slug].js → /products/category/subcategory
└── 404.js → Custom 404 page
🔗 Dynamic Routes
// pages/blog/[slug].js
import { useRouter } from 'next/router'
export default function BlogPost() {
const router = useRouter()
const { slug } = router.query
return (
<div>
<h1>Blog Post: {slug}</h1>
</div>
)
}
// pages/products/[...params].js - Catch-all routes
export default function Product() {
const router = useRouter()
const { params } = router.query
// params could be ['category', 'subcategory', 'item']
return (
<div>
<h1>Product: {params?.join(' / ')}</h1>
</div>
)
}
Rendering Methods
Next.js supports multiple rendering methods, allowing you to choose the best approach for each page.
📊 Static Site Generation (SSG)
Pages are generated at build time and served as static files.
// pages/posts/index.js
export default function Posts({ posts }) {
return (
<div>
{posts.map(post => (
<div key={post.id}>
<h2>{post.title}</h2>
<p>{post.excerpt}</p>
</div>
))}
</div>
)
}
// This function runs at build time
export async function getStaticProps() {
const posts = await fetchPosts()
return {
props: {
posts,
},
// Regenerate page every 60 seconds
revalidate: 60,
}
}
🖥️ Server-Side Rendering (SSR)
Pages are generated on each request.
// pages/profile.js
export default function Profile({ user }) {
return (
<div>
<h1>Welcome, {user.name}!</h1>
<p>Last login: {user.lastLogin}</p>
</div>
)
}
// This function runs on every request
export async function getServerSideProps(context) {
const { req } = context
const user = await getUserFromRequest(req)
return {
props: {
user,
},
}
}
🎯 Incremental Static Regeneration (ISR)
Combine benefits of static and dynamic rendering.
export async function getStaticProps() {
const posts = await fetchPosts()
return {
props: {
posts,
},
// Regenerate at most once per hour
revalidate: 3600,
}
}
export async function getStaticPaths() {
const paths = await getPostPaths()
return {
paths,
// Enable ISR for new pages
fallback: 'blocking',
}
}
📱 Client-Side Rendering (CSR)
Standard React behavior - render on the client.
import { useState, useEffect } from 'react'
export default function Dashboard() {
const [data, setData] = useState(null)
useEffect(() => {
fetch('/api/dashboard-data')
.then(res => res.json())
.then(setData)
}, [])
if (!data) return <div>Loading...</div>
return <div>{/* Dashboard content */}</div>
}
API Routes
Next.js allows you to create API endpoints as serverless functions, enabling full-stack development within a single project.
🔧 Creating API Routes
// pages/api/hello.js
export default function handler(req, res) {
res.status(200).json({ message: 'Hello from Next.js API!' })
}
// pages/api/users/[id].js - Dynamic API route
export default async function handler(req, res) {
const { id } = req.query
const { method } = req
switch (method) {
case 'GET':
const user = await getUserById(id)
res.status(200).json(user)
break
case 'PUT':
const updatedUser = await updateUser(id, req.body)
res.status(200).json(updatedUser)
break
case 'DELETE':
await deleteUser(id)
res.status(204).end()
break
default:
res.setHeader('Allow', ['GET', 'PUT', 'DELETE'])
res.status(405).end(`Method ${method} Not Allowed`)
}
}
// pages/api/posts.js - Handle form submissions
export default async function handler(req, res) {
if (req.method === 'POST') {
try {
const { title, content } = req.body
const post = await createPost({ title, content })
res.status(201).json(post)
} catch (error) {
res.status(500).json({ error: 'Failed to create post' })
}
} else {
res.status(405).json({ error: 'Method not allowed' })
}
}
Built-in Optimizations
🖼️ Image Optimization
import Image from 'next/image'
export default function Profile() {
return (
<div>
<Image
src="/profile.jpg"
alt="Profile picture"
width={300}
height={300}
priority // Load immediately
placeholder="blur" // Show blur while loading
/>
</div>
)
}
📝 Head Management
import Head from 'next/head'
export default function Post({ post }) {
return (
<>
<Head>
<title>{post.title} | My Blog</title>
<meta name="description" content={post.excerpt} />
<meta property="og:title" content={post.title} />
<meta property="og:description" content={post.excerpt} />
<meta property="og:image" content={post.image} />
</Head>
<article>
<h1>{post.title}</h1>
<div>{post.content}</div>
</article>
</>
)
}
🎨 CSS Support
// styles/Button.module.css
.button {
background: blue;
color: white;
border: none;
padding: 10px 20px;
}
.primary {
background: green;
}
// components/Button.js
import styles from '../styles/Button.module.css'
export default function Button({ children, primary }) {
const className = primary
? `${styles.button} ${styles.primary}`
: styles.button
return (
<button className={className}>
{children}
</button>
)
}
📦 Automatic Code Splitting
import { useState } from 'react'
import dynamic from 'next/dynamic'
// Load component only when needed
const DynamicChart = dynamic(
() => import('../components/Chart'),
{
loading: () => <p>Loading chart...</p>,
ssr: false // Don't render on server
}
)
export default function Dashboard() {
const [showChart, setShowChart] = useState(false)
return (
<div>
<button onClick={() => setShowChart(true)}>
Show Chart
</button>
{showChart && <DynamicChart />}
</div>
)
}
When to Use Next.js
- Marketing websites - Need SEO and fast loading
- E-commerce - Product pages need to be indexed
- Blogs & Documentation - Static content with good SEO
- Corporate websites - Professional sites with content
- Full-stack apps - Need both frontend and backend
- Portfolios - Personal or business showcases
- Internal dashboards - Private apps don't need SEO
- Admin panels - Behind authentication anyway
- Desktop-like apps - Complex interactions, less content
- Real-time apps - Chat, games, collaborative tools
- Simple SPAs - When SSR/SSG adds no value
- Mobile apps - React Native might be better
What's Next?
Next.js is a powerful framework that can handle everything from static sites to full-stack applications. It's an excellent choice when you need SEO, performance, and developer experience.
🚀 Continue Learning
- Popular Libraries - UI libraries and ecosystem tools
- Transition Guide - Complete migration strategies
- Learning Path - Structured approach to mastering React
- Resources - External learning materials and documentation