Ace Your Interviews 🎯

Browse our collection of interview questions across various technologies.

Next.jsBeginner

What is Next.js and how does it differ from React?

Answer

Next.js is a full-stack React framework built by Vercel. React is a UI rendering library — it only handles the component and rendering layer. Next.js adds everything React lacks: file-based routing, server-side rendering, static generation, API routes, image optimization, font optimization, and a build and deployment pipeline. Where React requires developers to choose and configure routing, data fetching, and optimization tools, Next.js provides opinionated built-in solutions for each.

Next.jsBeginner

What is the App Router in Next.js?

Answer

The App Router (stable since Next.js 13.4) is Next.js's current routing system built on React Server Components. Routes are defined by the file system — folders in the app/ directory become URL segments. Special files (page.tsx, layout.tsx, loading.tsx, error.tsx) define the UI at each segment. It replaces the Pages Router (pages/ directory) and enables Server Components, streaming, Server Actions, and nested layouts.

Next.jsBeginner

What is the difference between Server Components and Client Components?

Answer

Server Components (default in App Router) run only on the server — they can use async/await, access databases directly, and read environment variables, but can't use hooks, event handlers, or browser APIs. No JavaScript from Server Components reaches the browser. Client Components ('use client' directive) run in the browser — they can use useState, useEffect, event handlers, and browser APIs, but can't access server-only resources. The rule: server for data, client for interactivity.

Next.jsBeginner

What is the difference between SSR, SSG, and ISR in Next.js?

Answer

SSG (Static Site Generation): HTML built at build time, served from CDN, no server on request. Fastest, zero server cost. SSR (Server-Side Rendering): HTML generated fresh on every request by the server. Always up-to-date, personalized, but server runs for every visitor. ISR (Incremental Static Regeneration): Static HTML like SSG but regenerated on a schedule (revalidate: 3600 = every hour) or on-demand via revalidatePath/revalidateTag. Combines SSG speed with SSR freshness.

Next.jsBeginner

What is next/image and why should you use it?

Answer

next/image is Next.js's Image component that automatically: converts images to WebP or AVIF format (typically 50-80% smaller), generates responsive srcset for different device sizes, lazy-loads off-screen images by default, reserves space before load to prevent CLS (layout shift), and preloads LCP images when priority prop is added. Using <img> instead of next/image on important images directly costs Lighthouse Performance score and Core Web Vitals ranking.

Next.jsBeginner

How do you create an API endpoint in Next.js App Router?

Answer

Create a route.ts file inside the app/api/ directory. Export named functions for each HTTP method: export async function GET(request: NextRequest), export async function POST(request: NextRequest), etc. Use NextResponse.json() to return JSON responses. Route Handlers have access to the full Node.js runtime by default, or can run on the Edge Runtime with export const runtime = 'edge'.

Next.jsBeginner

What is a Server Action in Next.js?

Answer

Server Actions are async functions marked with 'use server' that run on the server but can be called from Client Components. They replace Route Handlers for form submissions and mutations — no separate API endpoint needed. Client Components pass a Server Action as a form's action prop or call it directly as a function. Server Actions can access the database directly, call revalidatePath to bust caches, and use redirect to navigate after mutations.

Next.jsBeginner

What is next/font and why does it matter?

Answer

next/font is Next.js's font loading solution. It downloads Google Fonts at build time, self-hosts them on your domain (eliminating the Google Fonts network request), generates optimal font-face CSS, and injects preload hints into the HTML — all without any JavaScript on the client. This eliminates FOUT (flash of unstyled text) which causes CLS, a Core Web Vitals metric that Google uses as a ranking factor.

Next.jsBeginner

How does file-based routing work in Next.js App Router?

Answer

Every folder inside app/ represents a URL segment. A page.tsx file makes the segment accessible. Dynamic segments use square brackets: [id] matches /products/any-id. Catch-all routes use [...slug]. Route groups use (name) and don't add to the URL. Layout.tsx wraps all pages in its segment and nested segments. Loading.tsx shows during page transitions. Error.tsx catches errors in the segment.

Next.jsBeginner

What is the purpose of layout.tsx in Next.js?

Answer

layout.tsx defines UI that is shared across multiple pages in its directory and all nested directories. Unlike page.tsx which re-renders on every navigation, layout.tsx persists across client-side navigations within its scope — meaning the sidebar doesn't flash when navigating between dashboard pages. The root layout.tsx (required) wraps the entire application and must include the html and body tags.

Next.jsIntermediate

Explain Next.js caching layers and how to control them.

Answer

Next.js has four caching layers: Request Memoization (deduplicates identical fetch() calls within one render), Data Cache (persists fetch() results across requests — controlled by next: { revalidate } or cache: 'no-store'), Full Route Cache (stores rendered Server Component output at build time for static routes), and Router Cache (client-side cache of RSC payloads for visited routes — 30s for dynamic, 5min for static). Control: revalidatePath() busts Full Route Cache for a URL. revalidateTag() busts Data Cache by tag. cache: 'no-store' opts a fetch out of Data Cache.

Next.jsIntermediate

When would you use a Server Action vs a Route Handler?

Answer

Server Actions: form submissions from Client Components, mutations triggered by user interactions within the same Next.js app, operations that need revalidatePath or redirect after completion. Route Handlers: public API endpoints for external consumers (mobile apps, third-party services), webhooks (Stripe, GitHub — must be accessible via HTTP), endpoints that need specific HTTP status codes, SSE (Server-Sent Events) or WebSocket upgrade, and any endpoint that needs to be called with plain fetch() from outside the app.

Next.jsIntermediate

How do you implement authentication in Next.js App Router?

Answer

Use Auth.js (NextAuth.js v5): configure providers (Google, Credentials) in auth.ts, export handlers to app/api/auth/[...nextauth]/route.ts, read session in Server Components with await auth() (no hook needed), read in Client Components with useSession(), protect routes at scale with Middleware that reads the session from the JWT cookie at the edge before any page renders. Middleware is the most performant protection layer — it redirects unauthorized users before any Server Component code executes.

Next.jsIntermediate

How does Partial Prerendering (PPR) work?

Answer

PPR splits a page into a static outer shell and dynamic inner sections bounded by React Suspense. The static shell is generated at build time and served from CDN instantly — it loads in milliseconds. Dynamic sections (personalized content, cart, recommendations) stream in after the shell. Users see meaningful content immediately even before personalized sections load. PPR is the middle ground between SSG (no personalization) and SSR (wait for all data before showing anything).

Next.jsIntermediate

How do you handle errors in Next.js App Router?

Answer

error.tsx files define error boundaries for route segments — Next.js automatically makes them Client Components with reset() and error props. The root app/error.tsx catches unhandled errors globally. For not-found errors, throw notFound() in a Server Component — Next.js renders the nearest not-found.tsx. For expected validation errors in Server Actions, return error objects rather than throwing — React's useFormState captures return values from Server Actions.

Next.jsIntermediate

What is generateStaticParams and when do you use it?

Answer

generateStaticParams defines which dynamic route segments to pre-build at build time. Return an array of params objects — Next.js generates a static HTML file for each. For routes not in generateStaticParams, behavior depends on the dynamicParams config: true (default) generates on-demand and caches, false returns 404. Use for: popular blog posts, featured product pages, stable reference pages. Skip for: user-specific pages, rarely-visited pages (let ISR handle them).

Next.jsIntermediate

How do you implement infinite scroll in Next.js?

Answer

Use TanStack Query's useInfiniteQuery with a Route Handler that accepts a cursor parameter. The Route Handler returns a page of items plus a nextCursor. useInfiniteQuery calls getNextPageData with the cursor, accumulates pages, and exposes fetchNextPage and hasNextPage. Trigger loading via an Intersection Observer (react-intersection-observer package) watching a sentinel div at the bottom of the list. This pattern works fully client-side after the initial server-rendered page load.

Next.jsIntermediate

How do you optimize bundle size in a Next.js application?

Answer

Automatic code splitting per route is built-in. Manual optimization: use dynamic() import for large components only needed on interaction (code splits them), import icon libraries granularly (import { ChevronDown } from 'lucide-react' not the whole library), add optimizePackageImports in next.config.ts for icon/component libraries, analyze with ANALYZE=true npm run build, lazy-load heavy components below the fold, use next/font to load only needed font subsets.

Next.jsIntermediate

What is middleware in Next.js and what are its common uses?

Answer

Middleware (middleware.ts at project root) runs before every matched request, at the edge — before any Server Component, Route Handler, or static file is served. Uses: authentication (redirect if no session cookie), locale detection (read Accept-Language header, redirect to /en or /hi), A/B testing (assign and persist variant via cookie), geo-targeting (redirect based on Vercel's geo headers), bot protection, rate limiting (with edge-compatible Redis like Upstash).

Next.jsIntermediate

How do you implement optimistic UI updates in Next.js?

Answer

With Server Actions: use React's useOptimistic hook — it immediately applies a pending state to the UI before the Server Action completes, then replaces it with the real result. For Client Components using TanStack Query: useMutation with onMutate callback that calls queryClient.cancelQueries and queryClient.setQueryData with the optimistic value, then onError to roll back via queryClient.setQueryData with the previous snapshot stored in onMutate context.

Next.jsIntermediate

What is tRPC and how does it integrate with Next.js?

Answer

tRPC (TypeScript Remote Procedure Call) creates end-to-end type-safe APIs — the client's TypeScript types for API calls are inferred directly from the server's router definition, with no code generation step. In Next.js: server router defined in server/trpc.ts, exposed via a Route Handler. Client uses TanStack Query under the hood — trpc.product.list.useQuery() is a regular React Query hook but with full TypeScript inference. Eliminates the type drift between Route Handler response shapes and client-side usage.

Next.jsAdvanced

How would you architect a Next.js application for a team of 20 engineers?

Answer

Turborepo monorepo with packages: apps/web (Next.js), packages/ui (shared Radix UI + Tailwind components), packages/db (Prisma schema + client), packages/config (TypeScript, ESLint, Tailwind configs). Feature-based folder structure in apps/web: app/(dashboard)/orders/, app/(marketing)/pricing/. tRPC for API type safety. Server Components for read paths, Server Actions for write paths. Each team owns a feature folder. Storybook in packages/ui. Playwright E2E per major user flow. GitHub Actions: lint, test, build, deploy on PR.

Next.jsAdvanced

How do you implement multi-tenancy in Next.js?

Answer

Subdomain-based multi-tenancy: Middleware reads the host header (app.acme.com → tenant=app, customer.yoursaas.com → tenant=customer). Route to the same Next.js pages but with the tenant identifier passed via a rewritten URL or a context. Tenant resolution in Middleware: look up the custom domain in the database (Upstash Redis for edge-compatible lookup), resolve to tenant ID, rewrite request. Per-tenant database isolation: either separate databases per tenant (row-level security in PostgreSQL) or a tenantId field on all tables with Prisma row filtering middleware.

Next.jsAdvanced

How do you implement streaming in Next.js App Router?

Answer

React Suspense is the streaming primitive. Wrap slow data-fetching Server Components in <Suspense fallback={<Skeleton />}>. Next.js streams HTML chunks — the Suspense fallback appears first, then is replaced by the resolved component's HTML as it arrives. Use separate async Server Components for each data source (product info, reviews, recommendations) each in their own Suspense boundary — they load in parallel and stream independently. loading.tsx is syntactic sugar for a Suspense boundary around the page.

Next.jsAdvanced

Describe the Next.js request lifecycle from client click to rendered HTML.

Answer
1.

User clicks a <Link> — Next.js client-side router intercepts. 2. Router checks if RSC payload is in Router Cache — serves it immediately if cached. 3. If not cached, fetch RSC payload from server (a special JSON-like React serialization, not full HTML). 4. Server receives RSC request, runs the matched Server Component tree, queries the database, renders HTML+RSC payload. 5. Streams response — outer shell first, then Suspense boundaries fill in. 6. Client receives RSC payload, patches the existing React tree (only changed parts). 7. Client Components in the new page hydrate. 8. RSC payload cached in Router Cache for 30s (dynamic) or 5min (static).

Next.jsAdvanced

How do you handle real-time features in Next.js?

Answer

WebSockets: custom server or a third-party service (Pusher, Ably, PartyKit) — Next.js doesn't support WebSocket upgrades natively. Pusher is simplest: client-side useEffect subscribes to channel, server-side Server Action or Route Handler publishes on mutation. Server-Sent Events: Route Handler with a ReadableStream that keeps the connection open and writes events. Polling: TanStack Query's refetchInterval for low-frequency real-time needs. For collaborative features: Liveblocks or PartyKit provide ready-made infrastructure compatible with Next.js.

Next.jsAdvanced

How do you implement Role-Based Access Control (RBAC) end-to-end in Next.js?

Answer
1.

Database: User model has role field (enum: USER, ADMIN, SELLER). 2. Auth.js: extend JWT callback to include role in token, session callback to expose role in session.user. 3. Middleware: read JWT, check role against route pattern — redirect /admin/* if role !== ADMIN. 4. Server Components: await auth(), check session.user.role — use notFound() or redirect() for unauthorized access. 5. Server Actions: check session at the start of every action — throw new Error('Unauthorized') or return error object. 6. UI: conditionally render admin UI based on session.user.role from useSession().

Next.jsAdvanced

How would you debug a Core Web Vitals issue in a Next.js application?

Answer

LCP > 2.5s: Check if LCP element (usually hero image) has priority prop on next/image. Profile with WebPageTest to find actual LCP element. Check if server response time (TTFB) is slow — indicates SSR without caching. Check if fonts block rendering. CLS > 0.1: Look for images without dimensions or fill+parent, ads without reserved space, fonts not using next/font, dynamic content injected above existing content. INP > 200ms: Profile with Chrome DevTools Performance — identify long tasks in main thread. Virtualize long lists (react-virtual), defer non-critical client JS with dynamic().

Next.jsAdvanced

How do you implement search functionality in a Next.js application?

Answer

Simple: URL-based with useSearchParams + Server Component re-render on URL change — no client state needed. Debounce in Client Component, push to URL, Server Component reads and queries DB. Algolia/Typesense: prebuilt search UI components (InstantSearch) + API keys set in Client Component environment variables. For large catalogs: index products in Algolia via webhook on product create/update. Hybrid: Server Component for initial results, TanStack Query for client-side search refinement as user types (debounced Route Handler calls).

Next.jsAdvanced

What is the React Cache API and how does it work with Next.js?

Answer

React's cache() function wraps an async function and memoizes it per request — identical calls within one React render cycle execute the function only once. In Next.js, use it to create reusable data functions that auto-deduplicate: const getProduct = cache(async (id: string) => db.product.findUnique({ where: { id } })). If ProductPage and RelatedProducts both call getProduct('abc'), only one DB query runs. Unlike Next.js fetch() memoization which only works with fetch(), cache() works with any async function including Prisma queries.

Next.jsAdvanced

How do you implement a headless CMS integration with Next.js?

Answer

Sanity: use next-sanity, configure GROQ queries as shared functions, fetch in Server Components with sanity.fetch(), tag fetches for revalidation (next: { tags: ['post'] }), create /api/revalidate Route Handler with webhook secret validation, configure Sanity to call it on publish. Contentful: use @contentful/rich-text-react-renderer, typed SDK, similar ISR pattern. Key: put API tokens in server-only environment variables, fetch in Server Components (never client-side), use on-demand revalidation webhooks so content changes are live within seconds.

Next.jsAdvanced

How do you implement database migrations safely in a production Next.js application?

Answer

Prisma Migrate: maintain migration history in prisma/migrations/. On deployment, run prisma migrate deploy (not prisma db push — that's for development) before starting the Next.js server. In CI/CD: run migrations as a separate job before the Next.js build job. Backup database before migration. Use expand-contract pattern for zero-downtime: first deploy adds new column (nullable), second deploy migrates data, third deploy makes column required and removes old column. Never auto-migrate in production — always manual review.

Ready for a real challenge?

Master Next.js