Why Next.js Changed Everything
When I first started with React, everything was client-side. SPAs were the norm, and we accepted the trade-offs: slow initial loads, SEO challenges, and large client bundles. Next.js changed that by making server rendering, routing, and production optimization part of the default developer experience.
If you are preparing for a senior frontend interview, Next.js is not just a framework to memorize. You need to understand how rendering, caching, data fetching, metadata, and deployment fit together.
Next.js Basics
Next.js is a React framework for building production web apps. It gives you routing, server-side rendering, static generation, image optimization, API endpoints, and build-time performance features out of the box.
- File-based routing with nested layouts
- Server Components and Client Components
- Multiple rendering strategies
- Built-in caching and revalidation
- SEO-friendly metadata APIs
- Production tooling for performance and deployment
The App Router Revolution
The App Router introduced in Next.js 13 wasn't just an update—it was a paradigm shift. Server Components by default, nested layouts, and streaming changed how I think about building web apps.
Core Folder Structure
1app/
2 layout.tsx
3 page.tsx
4 blog/
5 [slug]/
6 page.tsx
7 api/
8 revalidate/route.tsIn interviews, a strong answer is to explain that the App Router is built around route segments. Each folder maps to a route, and special files like layout, page, loading, error, and route control behavior.
Server Components: The Game Changer
Server Components mean zero JavaScript sent to the client for static content. Your database queries run on the server, your secrets stay secret, and your users get faster pages. It's not magic—it's just smart architecture.
- Zero bundle impact: Server Components don't add to client JavaScript
- Direct data access: Query databases without API layers
- Automatic code splitting: Only send what the client needs
- Streaming: Show content as it becomes ready
Example: Server Component Data Fetching
1async function PostsPage() {
2 const posts = await fetch("https://api.example.com/posts", {
3 cache: "force-cache",
4 }).then((res) => res.json());
5
6 return (
7 <ul>
8 {posts.map((post) => (
9 <li key={post.id}>{post.title}</li>
10 ))}
11 </ul>
12 );
13}Senior interview note: Server Components are ideal for data that does not require client interactivity. They reduce bundle size and move work to the server.
Client Components: When You Need Interactivity
Any component that uses browser-only APIs or React state must be a Client Component. You opt into this with the "use client" directive.
1"use client";
2
3import { useState } from "react";
4
5export function LikeButton() {
6 const [count, setCount] = useState(0);
7
8 return (
9 <button onClick={() => setCount(count + 1)}>
10 Likes: {count}
11 </button>
12 );
13}Interview answer to remember: client components increase the amount of JavaScript sent to the browser, so you should use them only where interactivity is required.
Rendering Strategies
Next.js gives you several rendering options, and senior developers need to know when to use each one.
Static Site Generation
Use static generation when the content is mostly the same for every visitor and can be generated ahead of time.
1export async function generateStaticParams() {
2 const posts = await fetch("https://api.example.com/posts").then((res) =>
3 res.json()
4 );
5
6 return posts.map((post) => ({ slug: post.slug }));
7}Server-Side Rendering
Use SSR when the page must be personalized or always fresh at request time. This is common for dashboards, authenticated views, and dynamic business data.
Incremental Static Regeneration
Revalidation lets you get static performance with periodic freshness. It is one of the most useful production features in Next.js.
1export const revalidate = 60;
2
3export default async function BlogPage() {
4 const posts = await fetch("https://api.example.com/posts", {
5 next: { revalidate: 60 },
6 }).then((res) => res.json());
7
8 return <div>{posts.length} posts</div>;
9}Caching: The Hidden Superpower
Next.js's caching system is sophisticated. There's the Data Cache, the Full Route Cache, and the Router Cache. Understanding when each kicks in—and how to invalidate them—is crucial for production apps.
My Caching Strategy
- Static content: Let it cache forever
- User-specific data: No cache, fetch fresh
- Semi-dynamic content: Time-based revalidation
- Critical updates: On-demand revalidation with tags
Example: On-Demand Revalidation
1import { revalidateTag } from "next/cache";
2
3export async function updatePostAction(formData: FormData) {
4 "use server";
5
6 // update the post in your database here
7
8 revalidateTag("posts");
9}Interview tip: explain the difference between cache for performance and invalidation for correctness. Production systems need both.
Patterns I Use Daily
Parallel Data Fetching
Never fetch sequentially when you can fetch in parallel. Using Promise.all() for independent data requests can cut your page load times dramatically.
1const [user, notifications, settings] = await Promise.all([
2 fetch("/api/user").then((res) => res.json()),
3 fetch("/api/notifications").then((res) => res.json()),
4 fetch("/api/settings").then((res) => res.json()),
5]);Suspense Boundaries
Strategic Suspense boundaries let you show the shell of your page immediately while slower data loads in the background. Users perceive your app as faster even when total load time is the same.
1import { Suspense } from "react";
2
3export default function Page() {
4 return (
5 <Suspense fallback={<p>Loading dashboard...</p>}>
6 <Dashboard />
7 </Suspense>
8 );
9}Routing, Layouts, and Navigation
The App Router makes routing predictable. Nested layouts let you share UI across pages without repeating code, and route groups help organize large apps.
1app/
2 layout.tsx
3 (marketing)/
4 page.tsx
5 (dashboard)/
6 layout.tsx
7 settings/page.tsxFor interviews, be ready to explain the difference between a layout and a page: a layout persists across navigation inside its segment, while a page is the leaf node that renders the route content.
Metadata and SEO
Next.js has first-class metadata support, which is important for SEO and social sharing. This is a core topic in senior interviews because it shows whether you know how apps become discoverable.
1import type { Metadata } from "next";
2
3export const metadata: Metadata = {
4 title: "My Blog Post",
5 description: "A deep dive into Next.js",
6 openGraph: {
7 title: "My Blog Post",
8 description: "A deep dive into Next.js",
9 },
10};Forms and Server Actions
Server Actions simplify form handling by letting you post directly to a server function. This reduces boilerplate and keeps sensitive logic on the server.
1"use client";
2
3import { saveProfile } from "./actions";
4
5export function ProfileForm() {
6 return (
7 <form action={saveProfile}>
8 <input name="name" placeholder="Your name" />
9 <button type="submit">Save</button>
10 </form>
11 );
12}1"use server";
2
3export async function saveProfile(formData: FormData) {
4 const name = formData.get("name");
5 // validate and persist to the database
6}Image Optimization and Performance
Performance is one of the biggest reasons teams choose Next.js. Image optimization, code splitting, and routing-level performance controls all help reduce page weight and improve user experience.
1import Image from "next/image";
2
3export function Hero() {
4 return (
5 <Image
6 src="/hero.png"
7 alt="Hero illustration"
8 width={1200}
9 height={700}
10 priority
11 />
12 );
13}Middleware and Edge Logic
Middleware runs before a request is completed. It is useful for auth redirects, locale handling, and request rewriting, but it should stay lightweight.
1import { NextResponse } from "next/server";
2import type { NextRequest } from "next/server";
3
4export function middleware(request: NextRequest) {
5 if (!request.cookies.get("session")) {
6 return NextResponse.redirect(new URL("/login", request.url));
7 }
8
9 return NextResponse.next();
10}API Routes and Route Handlers
Route Handlers are the App Router way to create API endpoints. They are useful for webhooks, lightweight backend logic, and integration points.
1import { NextResponse } from "next/server";
2
3export async function GET() {
4 return NextResponse.json({ ok: true });
5}Senior Interview Questions I Would Expect
- What is the difference between Server Components and Client Components?
- When would you choose SSR, SSG, or ISR?
- How does caching work in the App Router?
- What causes hydration issues in Next.js?
- How do Server Actions change form handling?
- Why would you use middleware, and what should you avoid there?
- How do metadata and Open Graph tags improve SEO?
- How do you reduce bundle size in a large app?
Short Answers That Interviewers Like
- Server Components reduce client JavaScript and are ideal for non-interactive content.
- Client Components are required for state, effects, and browser APIs.
- SSR is best for request-time freshness, SSG for static pages, and ISR for periodically updated pages.
- Cache invalidation is as important as caching itself.
- Use Server Actions when you want simpler server-side mutations with less API boilerplate.
What I'm Excited About
The React and Next.js ecosystem keeps evolving. Server Actions have simplified form handling. Partial Prerendering promises even more granular optimization. The future of web development is bright, and Next.js is leading the charge.
Practical Interview Prep Summary
If you want to speak confidently about Next.js in a senior interview, focus on explaining trade-offs. Know when to render on the server, when to push code to the client, how to keep content fresh, and how to keep the app fast and maintainable.
The best Next.js developers do not just use the framework features. They can explain why each feature exists, when it should be used, and what the cost is if it is used incorrectly.
Final Thoughts
Next.js isn't just a framework—it's a philosophy about how modern web apps should work. Fast by default, flexible when needed, and always pushing the boundaries of what's possible on the web.

Prabhath Madhushan
Full Stack Developer | Software Engineer
A passionate developer building scalable web applications with modern technologies. Always learning, always creating.
