CONCEPTS
App Router
🛣️- ❯ Layouts & Pages
- ❯ Loading UI
- ❯ Error Handling
- ❯ Parallel Routes
Server Components
⚡- ❯ RSC Rendering
- ❯ Client Boundaries
- ❯ Hydration
- ❯ Suspense
Data Fetching
💾- ❯ Extended fetch()
- ❯ Caching
- ❯ Revalidation (ISR)
- ❯ Server Actions
Optimizations
🚀- ❯ next/image
- ❯ next/font
- ❯ next/script
- ❯ Metadata API
FEATURES
01
Server Actions
Mutate data directly on the server
async function createPost(formData) { 'use server' }02
Middleware
Run code before a request is completed
export function middleware(request) {}03
API Routes
Build public APIs & Webhooks
export async function GET(request) {}04
Edge Runtime
Execute code at the network edge
export const runtime = 'edge'05
Dynamic Routes
Generate routes from dynamic data
app/blog/[slug]/page.tsx06
Metadata
Dynamic SEO and Open Graph tags
export const metadata = { title: '...' }PATTERNS
Server-Side Rendering (SSR)
Generate HTML on each request for dynamic content
Static Site Generation (SSG)
Pre-render HTML at build time for speed
Incremental Static Regeneration (ISR)
Update static pages in the background without rebuilds
Intercepting Routes
Load a route within the current layout (e.g., Modals)
Suspense Boundaries
Stream UI components progressively as data loads
EXERCISES
Build a Server-rendered Blogeasy
Create a User Dashboard with Auth.jsmedium
Implement Stripe Checkout Routemedium
Performant E-commerce with ISRhard
Build an AI Chatbot with Edge Runtimehard
SYNTAX_DEMO
page.tsx
import { Suspense } from 'react';
import { notFound } from 'next/navigation';
import { revalidatePath } from 'next/cache';
import { db } from '@/lib/db';
import { CreatePostForm } from './form';
// ============================================
// 1. DATA FETCHING (SERVER COMPONENT)
// ============================================
async function getPosts() {
// fetch() is extended by Next.js to auto-cache
const res = await fetch('https://api.example.com/posts', {
next: { revalidate: 3600 } // ISR: Revalidate every hour
});
if (!res.ok) throw new Error('Failed to fetch data');
return res.json();
}
// Database query inside a Server Component
async function getProfile(userId) {
const profile = await db.user.findUnique({ where: { id: userId } });
if (!profile) notFound(); // Triggers not-found.tsx
return profile;
}
// ============================================
// 2. SERVER ACTIONS (MUTATIONS)
// ============================================
async function createPostAction(formData) {
'use server'; // Marks function to execute securely on server
const title = formData.get('title');
const content = formData.get('content');
// Validate and Insert into DB
await db.post.create({ data: { title, content } });
// Purge cache and reload page data
revalidatePath('/blog');
}
// ============================================
// 3. PAGE COMPONENT (RSC)
// ============================================
// Generate Dynamic SEO Metadata
export async function generateMetadata({ params }) {
return {
title: `User Profile - ${params.id}`,
description: 'Dynamic user dashboard'
};
}
// Default Page Export
export default async function DashboardPage({ params }) {
// Fetching data concurrently
const postsData = getPosts();
const profileData = getProfile(params.id);
// Await the promises
const [posts, profile] = await Promise.all([postsData, profileData]);
return (
<main className="p-8">
<h1>Welcome, {profile.name}</h1>
{/* Streaming UI with Suspense */}
<Suspense fallback={<p>Loading your feed...</p>}>
<PostFeed posts={posts} />
</Suspense>
{/* Client Component injected with a Server Action */}
<CreatePostForm action={createPostAction} />
</main>
);
}