HomeBytesheetsRoadmapsUI TemplatesUI ToolsStack Discussion
75 Topics
Chapter•300 Minutes

Complete Next.js Progressive Master Question Bank

50 progressive Next.js interview questions covering client/server routing, rendering strategies, caching architecture, data fetching, security, and optimization techniques.

Q1: What is Next.js and why use it over plain React?

Next.js is a full-stack React framework built by Vercel. While plain React is a client-side rendering (CSR) library, Next.js provides hybrid rendering (SSR, SSG, ISR), file-based routing, automatic code splitting, image/font optimizations, Server Components, and API routes out of the box.

File-based Page Definition
// app/about/page.js -> Creates /about route automatically
export default function AboutPage() {
  return <h1>About Us</h1>;
}
💡 Creating page.js inside the app/about folder instantly maps it to the /about URL path.
Key Takeaways
  • Provides full-stack capabilities (Hybrid SSR, SSG, RSC, and API Route endpoints).
  • Enhances SEO, initial page load speeds, and Core Web Vitals automatically.
Knowledge Check

What primary performance drawback of traditional React Single Page Applications (SPAs) does Next.js solve?

Q2: What is the difference between the App Router and Pages Router in Next.js?

  • Pages Router (/pages): Legacy routing model using file names as routes. Uses getStaticProps and getServerSideProps for data fetching. All components default to Client Components.
  • App Router (/app): Modern router introduced in Next.js 13. Built on React Server Components (RSC), uses folder-based conventions (page.js, layout.js), nested layouts, streaming, and Server Actions.
Pages Router vs App Router Mental Model
App Router Directory Structure
app/
├── layout.js      # Shared root layout
├── page.js        # Root '/' route page
└── dashboard/
    ├── layout.js  # Nested '/dashboard' layout
    └── page.js    # '/dashboard' page route
💡 App Router uses directory hierarchies and special reserved file conventions.
Key Takeaways
  • App Router defaults all components to Server Components.
  • App Router supports nested layouts and streaming Suspense boundaries natively.
Knowledge Check

What component model do files inside the App Router (/app) adopt by default?

Q3: What are the main rendering modes supported by Next.js (SSR, SSG, ISR, CSR)?

  • SSR (Server-Side Rendering): HTML generated on every user request.
  • SSG (Static Site Generation): HTML built once at build time.
  • ISR (Incremental Static Regeneration): Re-generates static HTML pages in the background after deployment without a full site rebuild.
  • CSR (Client-Side Rendering): Rendered dynamically inside the browser.
Fetching Strategy Flags in App Router fetch()
// 1. SSG (Static Default)
fetch('https://api.com/data', { cache: 'force-cache' });

// 2. SSR (Dynamic per Request)
fetch('https://api.com/data', { cache: 'no-store' });

// 3. ISR (Revalidate every 60 seconds)
fetch('https://api.com/data', { next: { revalidate: 60 } });
💡 App Router configures rendering behavior through options in native fetch calls.
Key Takeaways
  • SSG offers maximum speed for static content (blogs, docs).
  • ISR updates static pages periodically on demand using background revalidation.
Knowledge Check

Which rendering strategy allows updating a static landing page periodically after site deployment without triggering a full rebuild?

Q4: What are the special file conventions in Next.js App Router?

The App Router reserves explicit file names inside route folders:

  • page.js: Defines route UI.
  • layout.js: Defines shared UI surrounding child pages (persists state across navigation).
  • template.js: Similar to layout, but creates a new instance on every page navigation.
  • loading.js: Creates automatic Suspense fallback UI.
  • error.js: Creates an Error Boundary wrapper.
Loading and Error Handlers
// app/dashboard/loading.js
export default function Loading() {
  return <p>Loading dashboard stats...</p>;
}

// app/dashboard/error.js (Must be a Client Component)
'use client';
export default function Error({ error, reset }) {
  return <button onClick={() => reset()}>Try Again</button>;
}
💡 loading.js wraps pages in Suspense; error.js isolates route errors inside an Error Boundary.
Key Takeaways
  • layout.js stays mounted and preserves internal component state during route navigation.
  • template.js re-mounts on every route transition, re-running effects.
Knowledge Check

What is the key functional difference between layout.js and template.js in the App Router?

Q5: How do React Server Components (RSC) differ from Client Components in Next.js?

Server Components run exclusively on the server, send zero JS bundle code to browsers, and can query databases directly. Client Components are marked with 'use client', run on both server (for initial HTML) and browser, and handle interactivity, state (useState), and event listeners.

Combining Server and Client Components
// app/page.js (Server Component)
import db from '@/lib/db';
import LikeButton from './LikeButton'; // Client Component

export default async function Page() {
  const post = await db.post.findUnique({ id: 1 });
  return (
    <div>
      <h1>{post.title}</h1>
      <LikeButton postId={post.id} /> {/* Interactive Child */}
    </div>
  );
}
💡 Server Components fetch database data directly and pass serialized props down to interactive Client Component children.
Key Takeaways
  • Server Components reduce client JS bundle size to zero bytes.
  • Use 'use client' at the top of a file only when event listeners or state hooks are required.
Knowledge Check

What happens if you attempt to use useState() inside a component without declaring 'use client' in the App Router?

Q6: What does the 'use client' directive actually define?

The 'use client' directive defines a boundary between the Server Component tree and the Client Component tree. Declaring 'use client' at the top of a file marks that module and all of its imported dependencies as Client Components.

Passing Server Components as Children to Client Boundaries
// ClientModal.js
'use client';
export default function ClientModal({ children }) {
  const [isOpen, setIsOpen] = useState(false);
  return isOpen ? <div className="modal">{children}</div> : null;
}

// Page.js (Server Component)
export default function Page() {
  return (
    <ClientModal>
      <ServerDataComponent /> {/* Remains a Server Component! */}
    </ClientModal>
  );
}
💡 Passing Server Components as children slots to Client Components keeps them rendered on the server.
Key Takeaways
  • 'use client' establishes a module dependency boundary, not just a single-file flag.
  • Keep 'use client' boundaries as low down the component tree as possible to minimize JS bundle size.
Knowledge Check

How can you render a Server Component inside a Client Component wrapper without turning the Server Component into a client bundle item?

Q7: How does the next/image Component optimize images?

The <Image /> component optimizes images automatically by:

  1. Format conversion: Serves WebP/AVIF images dynamically.
  2. Resizing: Generates responsive image srcsets based on device sizes.
  3. CLS prevention: Enforces explicit dimensions or aspect ratios to eliminate layout shifts.
  4. Lazy loading: Defers loading off-screen images until scrolled near viewport.
next/image Usage
import Image from 'next/image';
import profilePic from './profile.jpg';

export default function Avatar() {
  return (
    <Image
      src={profilePic}
      alt="User Avatar"
      width={200}
      height={200}
      placeholder="blur"
      priority // Loads immediately above the fold
    />
  );
}
💡 Setting priority disables lazy loading for above-the-fold hero assets to optimize LCP.
Key Takeaways
  • Prevents Cumulative Layout Shift (CLS) by reserving display dimensions.
  • Converts images on-demand to AVIF/WebP, resizing images to device viewport width.
Knowledge Check

Which prop should be added to a next/image component if the image is an above-the-fold Hero banner image?

Q8: How does next/font optimize custom typography and prevent layout shift?

next/font automatically downloads font files at build time and hosts them alongside static assets. It injects CSS size-adjust fallbacks to match font metrics, eliminating external network requests to Google Fonts and completely preventing Flash of Unstyled Text (FOUT) and Cumulative Layout Shift (CLS).

Configuring Google Fonts in Layout
import { Inter } from 'next/font/google';

const inter = Inter({ subsets: ['latin'], display: 'swap' });

export default function RootLayout({ children }) {
  return (
    <html lang="en" className={inter.className}>
      <body>{children}</body>
    </html>
  );
}
💡 Inter font files download at build time and apply via CSS class name selectors.
Key Takeaways
  • Zero external network requests at runtime; fonts are self-hosted automatically.
  • Eliminates FOUT and CLS using size-adjust CSS fallbacks.
Knowledge Check

Does next/font make browser network calls to Google Fonts servers when users visit the site in production?

Q9: How do Dynamic Routes, Catch-all, and Optional Catch-all routes work in Next.js?

  • Dynamic Route ([id]): Matches single segment parameter (/posts/1 -> { id: '1' }).
  • Catch-all ([...slug]): Matches multiple path segments (/shop/clothes/shoes -> { slug: ['clothes', 'shoes'] }). Requires segment to exist.
  • Optional Catch-all ([[...slug]]): Matches multiple segments AND root path (/shop -> { slug: undefined }).
Reading Dynamic Route Params in App Router
// app/shop/[[...slug]]/page.js
export default async function ShopPage({ params }) {
  const { slug } = await params; // Array or undefined
  return <p>Active Path Categories: {slug ? slug.join(' > ') : 'Root Shop'}</p>;
}
💡 Optional catch-all handles /shop, /shop/men, and /shop/men/shoes inside a single page file.
Key Takeaways
  • [id] captures a single path segment.
  • [...slug] captures array of segments; [[...slug]] also matches the base route without segments.
Knowledge Check

Which folder naming convention matches both /docs AND /docs/installation/setup?

Q10: What is generateStaticParams and how does it replace getStaticPaths?

In the App Router, generateStaticParams replaces the legacy getStaticPaths. Used inside dynamic routes ([id]), it returns an array of segment objects to pre-render routes at build time (SSG). Uncompiled routes fallback to dynamic on-demand rendering.

generateStaticParams Implementation
// app/posts/[id]/page.js
export async function generateStaticParams() {
  const posts = await fetch('https://api.com/posts').then(res => res.json());
  return posts.map(post => ({ id: String(post.id) }));
}

export default async function PostPage({ params }) {
  const { id } = await params;
  return <h1>Post ID: {id}</h1>;
}
💡 generateStaticParams outputs route parameters pre-rendered statically during build time.
Key Takeaways
  • Pre-renders dynamic routes ([id]) statically during build time.
  • Combines with export const dynamicParams = false to return 404 for non-generated paths.
Knowledge Check

What is the App Router equivalent of the legacy Pages Router getStaticPaths function?