An expert-level guide to Next.js. Exploring the App Router, SSR/ISR/SSG configurations, Metadata API, Server Actions, Middleware, and Core Web Vitals optimization.
page.tsx and layout.tsx files, leveraging React Server Components by default.export const revalidate = 60;).The App Router runs on React Server Components, prioritizing server-side rendering to deliver fast initial page loads.
app/
├── layout.tsx (Global Shell)
├── page.tsx (Home Route)
├── blog/
│ ├── page.tsx (Blog Hub Route)
│ └── [slug]/
│ └── page.tsx (Dynamic Article Route)
Next.js unifies rendering methods using standard fetch configuration parameters:
Fetch data fresh on every user request.
async function getDynamicData() {
const res = await fetch("https://api.example.com/data", { cache: "no-store" });
return res.json();
}
Fetch data at build time.
async function getStaticData() {
const res = await fetch("https://api.example.com/data");
return res.json();
}
Regenerate pages in the background after a specified number of seconds.
export const revalidate = 3600; // revalidate every hour
Next.js provides a robust Metadata API to configure SEO tags statically or dynamically.
import { Metadata } from "next";
// Static metadata
export const metadata: Metadata = {
title: "Ajit Dev Portfolio",
description: "DevOps & Full Stack developer website",
};
// Dynamic metadata
export async function generateMetadata({ params }): Promise<Metadata> {
const post = await fetchPost(params.slug);
return {
title: `${post.title} | Ajit Dev Blog`,
description: post.description,
openGraph: {
title: post.title,
description: post.description,
images: [{ url: post.ogImageUrl }],
},
};
}
Server Actions allow calling server-side functions directly from forms without writing API handlers.
// app/contact/actions.ts
"use server";
import { z } from "zod";
const formSchema = z.object({
email: z.string().email(),
message: z.string().min(10),
});
export async function submitContactForm(formData: FormData) {
const rawData = {
email: formData.get("email"),
message: formData.get("message"),
};
// Validate inputs on the server
const validated = formSchema.parse(rawData);
// Save to database or trigger email notifications
console.log("Saving contact record:", validated);
return { success: true };
}
Middleware runs before requests are completed, allowing you to rewrite paths, redirect routes, or check authentication tokens.
// middleware.ts
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
export function middleware(request: NextRequest) {
const token = request.cookies.get("session_token");
// Redirect unauthenticated users
if (!token && request.nextUrl.pathname.startsWith("/admin")) {
return NextResponse.redirect(new URL("/login", request.url));
}
return NextResponse.next();
}
next/image: Resizes images, uses modern WebP/AVIF formats, lazy-loads images, and prevents Layout Shifts (CLS).next/font: Downloads Google Fonts at build time, hosting them locally to remove external network calls."use client".route.ts used for?