Top Next.js Interview Questions & Answers 2026 With Real Examples


Next.js has become the go-to React framework for production applications in 2026. Whether you're a graduate entering Australia's tech market or an experienced developer targeting roles at companies like Atlassian, Canva, Xero, or REA Group, you will be asked Next.js interview questions.
This guide covers the 50 most commonly asked Next.js interview questions and answers, from fundamentals through to the App Router, Server Components, and performance optimisation. Each answer is written so you can actually say it out loud in an interview, not just understand it on paper.
Use the sections below to work through questions by difficulty. If you want to practise answering these live with a mentor who knows the Australian tech hiring process, scroll to the bottom.
Beginner Level Questions
1. What is Next.js, and why do developers implement it?
Next.js is a response system that allows server-side rendering and generating static websites. It provides out-of-the-box features like automatic code splitting, optimized performance, and simplified routing, making web development more efficient and developer-friendly.
2. Explain how server-side rendering (SSR) works in Next.js.
In Next.js, SSR permits rendering React components on the server, generating HTML for each request. This approach improves initial page load times and provides a better user experience by enhancing SEO compared to traditional client-side rendering.
3. Clarify the Difference Between Static Site Generation (SSG) and Server-Side Rendering (SSR)
SSG: Pages are produced at build time, ideal for content that doesn't change regularly.
SSR: Pages are rendered on demand for each request, perfect for dynamic content.
4. What is the reason for the pages catalog in Next.js?
The pages registry is principal to Next.js routing. Each record in this directory naturally becomes a route, with the filename deciding the path. For example, pages/about.js becomes /about
Intermediate Level Questions
5. Explain implementing dynamic routing in Next.js.
Dynamic routes are made using square brackets. For instance, pages/posts/[id]. js allows accessing posts with different IDs like /posts/1, /posts/2.
6. What is the getServerSideProps function?
getServerSideProps enables server-side rendering for a page. It runs on every request, allowing you to fetch data and pass it as props to the page component.
javascript
export async function getServerSideProps(context) {
const res = await fetch('https://api.example.com/data')
const data = await res.json()
return {
props: { data }
}
}
7. Clarify the Contrast Between getStaticProps and getServerSideProps
getStaticProps: Generates static pages at build time
getServerSideProps: Renders pages on-demand for each request
8. Explain handling API routes in Next.js.
API routes are generated in the pages/api directory. They permit building API endpoints as serverless capacities.
javascript
export default function handler(req, res) {
res.status(200).json({ message: 'Hello World' })
}
Senior Level Questions
9. What is Incremental Static Regeneration (ISR)?
ISR permits updating static pages after build time without remodifying the entire site. You can indicate a revalidation period to regenerate pages in the background.
javascript
export async function getStaticProps() {
return {
props: { data },
revalidate: 60 // Regenerate page every 60 seconds
}
}
10. How Can You Optimize Execution in Next.js?
Use Image Optimization with next/image
Implement code splitting
Leverage static generation
Use lazy loading for components
Minimize client-side JavaScript
🇦🇺 Preparing for a Next.js Interview in Australia?
Knowing the answers is only half the battle. Australian tech interviews often include live coding, system design, and behavioural rounds; all in the same session. Our mentors have worked at Atlassian, Canva, Xero, and ANZ and know exactly what local hiring teams are testing for.
11. Explain Next.js 13 App Router and Its Advantages
The App Router introduces a new way of handling routing with:
Nested layouts
Simplified data fetching
Parallel routing
Improved performance and code organization
12. What Are Middleware Functions in Next.js?
Middleware allows running code before a request is completed, enabling authentication, redirects, and request/response modifications.
javascript
export function middleware(request) {
// Perform authentication or logging
}
App Router & Server Components
The App Router, introduced in Next.js 13 and now the default, represents a fundamental shift in how Next.js applications are built. Expect multiple questions on this in any modern Next.js interview.
13. What is the App Router in Next.js and how is it different from the Pages Router?
The App Router uses the /app directory and was introduced in Next.js 13. The key differences are: the App Router supports React Server Components by default, introduces nested layouts, and uses a new file convention system (layout.js, page.js, loading.js, error.js). The Pages Router uses /pages and is the older approach where all components are Client Components by default. Most companies building new features today use the App Router.
📌 Australian hiring tip: If you're interviewing at a company that uses Next.js 13+, assume they use the App Router. Mention you're comfortable with both routers.
14. What are React Server Components (RSC) and why do they matter?
React Server Components run exclusively on the server and never send their JavaScript to the browser. This means faster page loads, smaller JS bundles, and more secure data fetching because sensitive logic stays on the server.
In Next.js App Router, all components are Server Components by default. You opt into client-side behaviour by adding the 'use client' directive at the top of a file.
// Server Component (default in App Router)
// app/users/page.tsx
async function UsersPage() {
// This runs on the server — no useEffect needed
const users = await fetch('https://api.example.com/users')
.then(res => res.json());
return (
<ul>
{users.map(u => <li key={u.id}>{u.name}</li>)}
</ul>
);
}
export default UsersPage;
15. When should you use 'use client' vs leaving a component as a Server Component?
Use 'use client' when your component needs: browser APIs (window, localStorage), React hooks (useState, useEffect, useRef), event listeners, or real-time interactivity.
Keep components as Server Components when: fetching data, accessing databases or file system, working with sensitive environment variables, or rendering static content. The rule of thumb — push 'use client' as far down the component tree as possible.
'use client'; // ← This makes it a Client Component
import { useState } from 'react';
export function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(c => c + 1)}>{count}</button>;
}
16. What is the purpose of layout.js in the App Router?
A layout.js file defines UI that is shared across multiple pages and persists between route changes; it does NOT re-render when navigating between child routes. This is ideal for navigation bars, sidebars, and footers. Layouts can be nested, so a /dashboard/layout.js wraps all dashboard pages while the root /app/layout.js wraps everything.
// app/layout.tsx — Root layout (required)
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang='en'>
<body>
<nav>Global Nav</nav>
{children}
<footer>Footer</footer>
</body>
</html>
);
}
17. What is the difference between layout.js and template.js?
Both wrap child pages, but layouts persist across navigations (state is preserved), while templates create a new instance on every navigation (state resets). Use template.js when you need enter/exit animations between routes or when you want to reset page-specific state on navigation. In practice, layout.js is used far more commonly.
📌 This is a subtle distinction interviewers use to test whether you've actually built with the App Router.
18. How do loading.js and error.js work in the App Router?
loading.js automatically wraps your page.js in a React Suspense boundary. When your page is fetching data, Next.js shows the loading UI instantly without any extra code.
error.js creates an Error Boundary for its route segment. If a component in that route throws an error, Next.js shows the error UI instead of crashing the whole app. Both files let you handle loading and error states at the route level rather than inside individual components.
// app/dashboard/loading.tsx
export default function Loading() {
return <div>Loading dashboard...</div>;
}
// app/dashboard/error.tsx
'use client'; // Error components must be Client Components
export default function Error({ error, reset }) {
return (
<div>
<p>Something went wrong: {error.message}</p>
<button onClick={reset}>Try Again</button>
</div>
);
}
19. How does data fetching work in the App Router?
In the App Router, you fetch data directly inside Server Components using async/await, no getServerSideProps or getStaticProps needed. Next.js extends the native fetch API with built-in caching and revalidation controls.
You control caching with the cache option: fetch(url, { cache: 'force-cache' }) for static data, fetch(url, { cache: 'no-store' }) for always-fresh data, or fetch(url, { next: { revalidate: 60 } }) for ISR-style revalidation every 60 seconds.
// app/products/page.tsx
async function ProductsPage() {
// Static — cached at build time
const staticData = await fetch('https://api.example.com/products', {
cache: 'force-cache'
});
// Dynamic — fresh on every request
const liveData = await fetch('https://api.example.com/live', {
cache: 'no-store'
});
// ISR — revalidate every 60 seconds
const revalidatedData = await fetch('https://api.example.com/news', {
next: { revalidate: 60 }
});
}
20. What are Server Actions in Next.js?
Server Actions are async functions that run on the server but can be called directly from Client Components, like form submissions or button clicks. They're defined with the 'use server' directive and eliminate the need to create API routes for simple server-side mutations. They're the modern way to handle form submissions in Next.js.
// app/actions.ts
'use server';
export async function createUser(formData: FormData) {
const name = formData.get('name');
await db.user.create({ data: { name } });
revalidatePath('/users');
}
// app/new-user/page.tsx
import { createUser } from '../actions';
export default function NewUserPage() {
return (
<form action={createUser}>
<input name='name' />
<button type='submit'>Create</button>
</form>
);
}
📌 Server Actions work even without JavaScript enabled in the browser, a significant accessibility and resilience advantage.
21. What is Parallel Routing in Next.js App Router?
Parallel Routes allow you to render multiple pages simultaneously in the same layout using named slots (defined with @folder convention). This is useful for dashboards where you want to load a sidebar and main content independently, or for modals that overlay a page. Each slot can have its own loading.js and error.js.
// app/dashboard/layout.tsx
export default function DashboardLayout({
children,
analytics, // @analytics slot
team, // @team slot
}: {
children: React.ReactNode
analytics: React.ReactNode
team: React.ReactNode
}) {
return (
<div>
{children}
{analytics}
{team}
</div>
);
}
22. How do you handle metadata (SEO) in the App Router?
The App Router has a built-in Metadata API that replaces the old next/head approach. You export a metadata object or a generateMetadata function from any page.js or layout.js file. Next.js automatically merges metadata from parent layouts with child pages.
// app/blog/[slug]/page.tsx
import { Metadata } from 'next';
// Static metadata
export const metadata: Metadata = {
title: 'My Blog Post',
description: 'An article about Next.js',
openGraph: { title: 'My Blog Post', images: ['/og.png'] }
};
// Dynamic metadata
export async function generateMetadata({ params }): Promise<Metadata> {
const post = await getPost(params.slug);
return {
title: post.title,
description: post.excerpt,
};
}
23. What is Streaming in Next.js and how does it improve performance?
Streaming allows Next.js to send HTML to the browser progressively rather than waiting for all data to load before sending anything. Using React Suspense, you can wrap slow-loading components so the fast parts of your page appear instantly while the slower parts stream in. This dramatically improves Time to First Byte (TTFB) and perceived performance.
// app/dashboard/page.tsx
import { Suspense } from 'react';
import { SlowComponent } from './SlowComponent';
import { FastComponent } from './FastComponent';
export default function Dashboard() {
return (
<div>
<FastComponent /> {/* Renders immediately */}
<Suspense fallback={<div>Loading slow data...</div>}>
<SlowComponent /> {/* Streams in when ready */}
</Suspense>
</div>
);
}
24. How does middleware work in Next.js?
Middleware runs before a request is completed, before the page renders and before the cache is checked. It's defined in a middleware.ts file at the root of your project. Common uses include: authentication checks, redirects, A/B testing, geolocation-based routing, and request header modification. Middleware runs on the Edge Runtime, making it extremely fast.
// middleware.ts (root of project)
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
// Check for auth token
const token = request.cookies.get('auth-token');
if (!token && request.nextUrl.pathname.startsWith('/dashboard')) {
return NextResponse.redirect(new URL('/login', request.url));
}
return NextResponse.next();
}
export const config = {
matcher: ['/dashboard/:path*'],
};
25. What is generateStaticParams and when would you use it?
generateStaticParams replaces getStaticPaths in the App Router. It tells Next.js which dynamic route values to pre-render at build time. For example, if you have a blog with 100 posts, you use generateStaticParams to pre-render all 100 post pages as static HTML. Any paths not returned will be generated on-demand and cached (similar to ISR).
// app/blog/[slug]/page.tsx
export async function generateStaticParams() {
const posts = await getPosts();
return posts.map((post) => ({
slug: post.slug,
}));
}
export default async function BlogPost({ params }) {
const post = await getPost(params.slug);
return <article>{post.content}</article>;
}
Performance, Authentication & Production (Senior-Level)
26. How do you optimise images in Next.js?
Use the built-in next/image component instead of a plain <img> tag. It automatically serves images in modern formats (WebP/AVIF), resizes for the requesting device, lazy loads by default, and prevents layout shift by requiring width and height props. For above-the-fold images, add priority={true} to preload them.
import Image from 'next/image';
export function HeroImage() {
return (
<Image
src='/hero.jpg'
alt='Hero banner'
width={1200}
height={600}
priority // Preload — use for above-the-fold images
sizes='(max-width: 768px) 100vw, 1200px'
/>
);
}
27. What is the difference between revalidatePath and revalidateTag in Next.js?
Both are used to invalidate the Next.js cache on-demand (usually from a Server Action or API route after a mutation).
revalidatePath('/blog') invalidates all cached data for a specific URL path. revalidateTag('posts') invalidates all fetch requests that were tagged with that tag using fetch(url, { next: { tags: ['posts'] } }). Tags are more flexible because you can revalidate multiple pages at once that share the same data source.
// Revalidate by path
import { revalidatePath } from 'next/cache';
revalidatePath('/blog');
// Revalidate by tag (more flexible)
import { revalidateTag } from 'next/cache';
revalidateTag('blog-posts');
// Tag a fetch request
const data = await fetch('https://api.example.com/posts', {
next: { tags: ['blog-posts'] }
});
28. How would you implement authentication in a Next.js App Router application?
The recommended approach in 2026 is to use Auth.js (formerly NextAuth.js) v5, which is built for the App Router. You configure providers (Google, GitHub, credentials, etc.) in an auth.ts file, protect routes using middleware, and access the session in Server Components using the auth() helper. For enterprise apps, you might integrate with an identity provider like Auth0 or Clerk instead.
// auth.ts
import NextAuth from 'next-auth';
import GitHub from 'next-auth/providers/github';
export const { handlers, auth, signIn, signOut } = NextAuth({
providers: [GitHub],
});
// middleware.ts — protect routes
export { auth as middleware } from './auth';
export const config = { matcher: ['/dashboard/:path*'] };
// Server Component — access session
import { auth } from '@/auth';
export default async function Dashboard() {
const session = await auth();
return <div>Hello {session?.user?.name}</div>;
}
29. What is the Next.js Font system and why should you use it?
next/font automatically optimises web fonts by hosting them locally (even Google Fonts), eliminating the external network request to Google's servers. This improves privacy, performance, and removes layout shift because fonts are pre-loaded with the correct size. Fonts are applied using CSS variables and work seamlessly with Tailwind CSS.
// app/layout.tsx
import { Inter } from 'next/font/google';
const inter = Inter({
subsets: ['latin'],
display: 'swap',
variable: '--font-inter',
});
export default function RootLayout({ children }) {
return (
<html className={inter.variable}>
<body>{children}</body>
</html>
);
}
30. How do you implement internationalisation (i18n) in Next.js App Router?
In the App Router, i18n is implemented manually or via libraries like next-intl. The common pattern is to use dynamic segments for the locale (/en/about, /fr/about), middleware to detect and redirect users to their locale, and JSON translation files loaded in Server Components. The App Router removed the built-in i18n routing config that existed in the Pages Router.
// middleware.ts — detect locale
import { match } from '@formatjs/intl-localematcher';
import Negotiator from 'negotiator';
const locales = ['en', 'fr', 'de'];
const defaultLocale = 'en';
export function middleware(request) {
const pathname = request.nextUrl.pathname;
const hasLocale = locales.some(locale => pathname.startsWith(`/${locale}`));
if (!hasLocale) {
return Response.redirect(new URL(`/${defaultLocale}${pathname}`, request.url));
}
}
31. How do you handle environment variables in Next.js?
Next.js loads environment variables from .env.local, .env.production, and .env files. Variables are server-only by default, they are never exposed to the browser. To expose a variable to the client side, prefix it with NEXT_PUBLIC_ (e.g., NEXT_PUBLIC_API_URL).
Never put secret keys in NEXT_PUBLIC_ variables they will be visible in the browser's JavaScript bundle.
# .env.local
DATABASE_URL=postgres://... # Server-only
API_SECRET_KEY=abc123 # Server-only
NEXT_PUBLIC_API_URL=https://api.example.com # Exposed to browser
// In a Server Component (can access all)
const secret = process.env.API_SECRET_KEY;
// In a Client Component (only NEXT_PUBLIC_ vars)
const apiUrl = process.env.NEXT_PUBLIC_API_URL;
32. What is the Route Handler in Next.js App Router and how does it replace API routes?
Route Handlers replace the /pages/api directory in the App Router. They're defined as route.ts files inside the /app directory and support all HTTP methods using named exports. They support the same Edge Runtime and Node.js Runtime options as pages.
// app/api/users/route.ts
import { NextRequest, NextResponse } from 'next/server';
export async function GET(request: NextRequest) {
const users = await db.user.findMany();
return NextResponse.json(users);
}
export async function POST(request: NextRequest) {
const body = await request.json();
const user = await db.user.create({ data: body });
return NextResponse.json(user, { status: 201 });
}
33. What are the different rendering strategies in Next.js and when would you choose each?
Static Rendering (default): Pages are rendered at build time. Best for content that doesn't change often blogs, marketing pages, documentation.
Dynamic Rendering: Pages render on every request. Triggered automatically when you use cookies(), headers(), or searchParams, or fetch with cache: 'no-store'. Best for personalised dashboards, real-time data.
Streaming: Combines static shell with streamed dynamic content. Best for dashboards where some parts are fast and others are slow.
ISR (Incremental Static Regeneration): Static pages that revalidate in the background. Best for e-commerce product pages, news sites.
📌 In Australian interviews, you'll often be asked to justify which strategy you'd use for a specific product. Prepare a concrete example for each.
34. How does Next.js handle caching and what are the four caching layers?
Next.js has four distinct caching mechanisms:
(1) Request Memoization — deduplicates identical fetch calls within a single render;
(2) Data Cache — persists fetch results across requests and deployments (can be revalidated);
(3) Full Route Cache — stores rendered HTML and RSC payloads on the server;
(4) Router Cache — client-side cache of RSC payloads for visited routes.
Understanding these layers is important for debugging stale data issues in production, which is a common senior interview question.
35. How would you optimise a slow Next.js page?
Start by measuring: use Lighthouse, Chrome DevTools, and Next.js's built-in analytics. Common optimisations include:
(1) Move data fetching to Server Components to reduce client JS;
(2) Use Streaming with Suspense to show content progressively;
(3) Implement lazy loading for below-fold components with dynamic import();
(4) Optimise images with next/image;
(5) Review and reduce third-party scripts;
(6) Use next/font to eliminate font layout shift;
(7) Check if pages can use static rendering instead of dynamic.
// Lazy load a heavy component
import dynamic from 'next/dynamic';
const HeavyChart = dynamic(() => import('./HeavyChart'), {
loading: () => <div>Loading chart...</div>,
ssr: false, // Don't render on server
});
36. What is the Edge Runtime in Next.js and when would you use it?
The Edge Runtime is a lightweight JavaScript runtime (based on Web APIs, not Node.js) that runs your code at CDN edge nodes closest to the user. It has extremely low latency because there's no cold start and requests are handled geographically close to the user. It's ideal for middleware, A/B testing, authentication checks, and personalisation. The trade-off is it doesn't support all Node.js APIs (no file system access, limited npm packages).
// Route Handler on the Edge
export const runtime = 'edge';
export async function GET(request: Request) {
return new Response('Hello from the edge!', { status: 200 });
}
37. How would you deploy a Next.js app and what should you consider for production?
The simplest deployment is Vercel (built by the Next.js team) you connect your GitHub repo and it handles everything automatically. For self-hosting, you can deploy to AWS, GCP, or Azure using Docker, or use platforms like Railway, Render, or Fly.io.
For production checklist: set all environment variables in your hosting platform (never commit secrets); enable logging and error monitoring (Sentry, Datadog); configure proper caching headers; set up a CI/CD pipeline to run tests before deploying; monitor Core Web Vitals in Search Console.
# Dockerfile for self-hosting
FROM node:20-alpine AS base
FROM base AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
FROM base AS runner
WORKDIR /app
ENV NODE_ENV production
COPY --from=builder /app/.next ./.next
EXPOSE 3000
CMD ['node_modules/.bin/next', 'start']
What Australian Tech Companies Actually Ask in Next.js Interviews
Australia's tech hiring market has some patterns worth knowing if you're preparing for Next.js roles specifically.
Companies using Next.js in Australia
Canva — heavy React/Next.js usage across marketing and product surfaces
Atlassian — uses Next.js for documentation sites and internal tooling
Xero — progressive adoption of Next.js for their product frontend
REA Group — Next.js for property listing pages and SEO-critical surfaces
Afterpay / Block — Next.js for checkout and merchant portals
Culture Amp — React ecosystem, increasingly App Router
What Australian interviews tend to focus on
System design rounds: you'll often be asked to design a full-stack feature using Next.js, not just answer trivia
Live coding: expect 45–60 minute sessions building a feature from scratch
Performance trade-offs: they want to know you understand WHY you'd choose SSR vs SSG, not just what they mean
Behavioural rounds alongside technical STAR-format answers about past projects
Tips for Australian tech interviews specifically
Research the company's tech stack before the interview; check their engineering blog and GitHub
Mention familiarity with Vercel, AWS Amplify, or whatever deployment they use
Ask about their rendering strategy in the interview; it signals you think at an architectural level
Accessibility (WCAG) comes up more in AU interviews than in US/UK roles
🇦🇺 Want to Practice with Someone Who Knows Australian Tech Interviews?
EmergiMentors connects you with senior engineers who have been through hiring processes at Australian tech companies. They know what Canva, Atlassian, and Xero interviewers actually ask and they'll help you nail it. Sessions are 1:1, tailored to your experience level, and focused on the Australian job market.
Next.js interviews in 2026 are demanding. Companies expect you to understand not just what SSR and SSG mean, but why you'd choose one over the other for a specific product, how the App Router changes the way you think about data fetching, and how to optimise a real application under constraints.
The questions in this guide cover the full range from fundamentals that catch juniors out, to App Router and Server Component questions that separate mid-level developers from seniors.
Reading the answers is a start. But in a live interview, you need to articulate them clearly under pressure, handle follow-up questions, and connect your answers to real projects you've worked on. That's a skill that takes practice.
🇦🇺 Ready to Put This Into Practice?
Emergi Mentors runs 1:1 mock technical interviews with senior engineers who know the Australian tech market. We'll go through Next.js questions like these, give you real-time feedback on your answers, and help you prepare for the system design and behavioural rounds that come alongside the technical test. Sessions are tailored to your target companies and experience level.






































