Next.js Lesson 29 – Next.js Interview Questions | Dataplexa
LESSON 29

Next.js Interview Questions

Master the most common Next.js interview questions with real-world scenarios and in-depth explanations to land your dream developer role.

Walking into a Next.js interview can feel overwhelming. You know how to build apps, but can you explain getStaticProps in two sentences? Can you compare different rendering strategies on the spot? This lesson covers the most frequent Next.js interview questions, complete with the reasoning behind each answer. These questions come from actual interviews at companies like Vercel, GitHub, and other tech companies using Next.js in production. Each answer includes not just the "what" but the "why" — understanding the reasoning behind Next.js features matters more than memorizing definitions.

Core Next.js Concepts

The foundation questions always start here. Interviewers want to know you understand why Next.js exists and what problems it solves compared to plain React. Question: What is Next.js and why would you use it over Create React App? This classic opener tests your understanding of the fundamental value proposition. Next.js is a React framework that provides structure and performance optimizations out of the box. Unlike Create React App, which gives you a blank React setup, Next.js includes built-in solutions for routing, API routes, different rendering strategies, and deployment optimization. The key difference lies in rendering strategies. Create React App only does client-side rendering — your JavaScript bundle loads in the browser, then renders the page. Next.js offers server-side rendering, static generation, and incremental static regeneration. Think of it like the difference between assembling furniture at home (CRA) versus buying pre-assembled furniture that arrives ready to use (Next.js).
// Create React App - client-side only
// User sees blank screen until JS loads and executes
function App() {
  const [articles, setArticles] = useState([])
  
  useEffect(() => {
    // API call happens after page loads
    fetchArticles().then(setArticles)
  }, [])
  
  return <div>{articles.map(article => ...)}</div>
}

// Next.js - pre-rendered with data
// User sees complete page immediately
export default function NewsWave({ articles }) {
  // Articles already loaded on server
  return <div>{articles.map(article => ...)}</div>
}

export async function getStaticProps() {
  // Runs at build time, not in browser
  const articles = await fetchArticles()
  return { props: { articles } }
}
Question: Explain the difference between pages directory and app directory in Next.js 13+. This question tests knowledge of Next.js evolution. The pages directory uses file-based routing where each file becomes a route. The app directory introduces layouts, nested routing, and React Server Components by default. Pages directory treats every file as a page component. You export a React component, and Next.js automatically creates the route. Simple and predictable. The app directory uses folders for routes and special files like page.js for the actual component, layout.js for shared UI, and loading.js for loading states.
Project Structure Comparison
📁 pages directory (old)
📄 index.js → /
📄 about.js → /about
📄 articles/[slug].js → /articles/[slug]
📁 app directory (new)
📄 layout.js (root layout)
📄 page.js → /
📁 about/
📄 page.js → /about
📁 articles/[slug]/
📄 page.js → /articles/[slug]
📄 loading.js

Data Fetching and Rendering

These questions dive into Next.js rendering strategies. Interviewers love asking about getStaticProps, getServerSideProps, and when to use each one. Question: When would you use getStaticProps versus getServerSideProps? This question tests your understanding of performance tradeoffs and user experience. getStaticProps runs at build time and creates static HTML files. Perfect for content that changes rarely, like blog posts or marketing pages. The trade-off is that data gets stale until the next build. getServerSideProps runs on every request, giving you fresh data but slower page loads. Use this for user-specific content, real-time data, or pages where freshness matters more than speed. Think of a user dashboard versus a company about page.
Rendering Strategy Decision Tree
Use getStaticProps when:
• Content changes rarely (blog posts, documentation)
• Same content for all users
• SEO important, speed critical
• Can rebuild when content changes

Use getServerSideProps when:
• Content changes frequently
• User-specific data (dashboards, profiles)
• Real-time requirements
• Cannot predict content at build time
// getStaticProps - NewsWave article page
// Builds once, serves to everyone, super fast
export async function getStaticProps({ params }) {
  const article = await fetchArticle(params.slug)
  
  return {
    props: { article },
    revalidate: 3600 // Rebuild every hour
  }
}

// getServerSideProps - NewsWave user dashboard
// Runs every request, always fresh, slower
export async function getServerSideProps({ req }) {
  const session = await getSession(req)
  const bookmarks = await fetchUserBookmarks(session.userId)
  
  return {
    props: { bookmarks }
  }
}
Question: Explain Incremental Static Regeneration (ISR) and provide a use case. ISR combines the benefits of static generation with the freshness of server-side rendering. You get fast static pages that can update automatically without rebuilding the entire site. Perfect for content that changes occasionally but needs to stay fresh. The magic happens with the revalidate property. After the specified time passes, the next visitor triggers a background regeneration. They still get the cached version immediately, but Next.js updates the static file behind the scenes. Subsequent visitors get the updated version.
// ISR perfect for NewsWave trending articles
// Fast static delivery + automatic updates
export default function TrendingPage({ articles }) {
  return (
    <div>
      <h1>Trending on NewsWave</h1>
      {articles.map(article => (
        <ArticleCard key={article.id} article={article} />
      ))}
    </div>
  )
}

export async function getStaticProps() {
  const articles = await fetchTrendingArticles()
  
  return {
    props: { articles },
    revalidate: 300 // Update every 5 minutes
  }
}

Routing and Navigation

Routing questions test your understanding of Next.js file-based routing system and dynamic routes. These concepts confuse developers coming from React Router. Question: How do dynamic routes work in Next.js? Explain with nested dynamic routes. Dynamic routes use square brackets in file names. [slug].js captures one parameter, [...params].js captures multiple. The parameter names become available in router.query or through getStaticProps params. For NewsWave, you might have /category/[name]/[page].js to handle both the category name and pagination. Next.js automatically parses the URL and provides both values.
// File: pages/category/[name]/[page].js
// Handles /category/tech/2, /category/sports/1, etc.
export default function CategoryPage({ articles, category, currentPage }) {
  return (
    <div>
      <h1>{category} Articles - Page {currentPage}</h1>
      {articles.map(article => (
        <ArticlePreview key={article.id} article={article} />
      ))}
    </div>
  )
}

export async function getStaticProps({ params }) {
  // params.name = "tech", params.page = "2"
  const articles = await fetchCategoryArticles(params.name, params.page)
  
  return {
    props: {
      articles,
      category: params.name,
      currentPage: parseInt(params.page)
    }
  }
}
Question: What's the difference between client-side and server-side navigation in Next.js? Next.js automatically optimizes navigation. The Link component provides client-side navigation — it prefetches the destination page and updates the URL without a full page reload. Regular anchor tags cause full page refreshes, losing React state and requiring complete reloads. Client-side navigation feels instant because JavaScript handles the route change. Server-side navigation (anchor tags or window.location) requires a round trip to the server. For internal navigation, always use Next.js Link components.

Performance and Optimization

Performance questions reveal your understanding of Next.js built-in optimizations and when to apply additional techniques. Question: How does Next.js Image component improve performance compared to regular img tags? The Image component provides automatic optimizations that regular img tags lack. It serves images in modern formats (WebP, AVIF) when browsers support them, automatically resizes images based on device requirements, and includes lazy loading by default. The component also prevents Cumulative Layout Shift by reserving space before the image loads. Most importantly, Next.js generates multiple image sizes at build time or on-demand. A mobile user gets a 400px image while desktop users get 1200px versions. This dramatically reduces bandwidth usage and loading times.
// Regular img - NewsWave article header (not optimized)
<img 
  src="/articles/breaking-news.jpg" 
  alt="Breaking news"
  style={{ width: '100%' }} 
/>

// Next.js Image - automatic optimization
import Image from 'next/image'

<Image
  src="/articles/breaking-news.jpg"
  alt="Breaking news"
  width={800}
  height={400}
  priority // Load immediately for above-fold images
  sizes="(max-width: 768px) 100vw, 800px" // Responsive sizing
/>
Question: Explain code splitting in Next.js and how it improves performance. Next.js automatically splits your code by pages. Each page gets its own JavaScript bundle, so users only download code for the current page. When they navigate to a new page, Next.js downloads that page's bundle in the background. This automatic splitting means your homepage bundle doesn't include code for your admin dashboard. A blog reader never downloads article editing functionality. Combined with Link component prefetching, users get instant navigation with minimal bundle sizes.

API Routes and Full-Stack Features

These questions test your knowledge of Next.js as a full-stack framework, not just a React renderer. Question: How do API routes work in Next.js? When would you use them versus external APIs? API routes let you create backend endpoints inside your Next.js app. Files in the pages/api directory become API endpoints. Perfect for handling form submissions, authentication, or proxying external APIs to hide API keys. Use API routes for simple backend logic, authentication handlers, webhook receivers, or when you need server-side processing without setting up a separate backend. For complex business logic or when you need a separate backend team, external APIs make more sense.
// File: pages/api/newsletter.js
// NewsWave newsletter signup endpoint
export default async function handler(req, res) {
  if (req.method !== 'POST') {
    return res.status(405).json({ error: 'Method not allowed' })
  }
  
  const { email } = req.body
  
  try {
    // Add to newsletter service (hide API key on server)
    await subscribeToNewsletter(email)
    res.status(200).json({ success: true })
  } catch (error) {
    res.status(500).json({ error: 'Subscription failed' })
  }
}
Question: How do environment variables work in Next.js? What's the difference between server and client variables? Next.js separates server-side and client-side environment variables for security. Variables without a prefix stay on the server — perfect for API keys and database URLs. Variables prefixed with NEXT_PUBLIC_ get bundled into the client code, making them accessible in browser JavaScript. This separation prevents accidental exposure of secrets. Your database password stays on the server, while your analytics tracking ID can be public. Never put sensitive data in NEXT_PUBLIC_ variables — they become visible to everyone.

Advanced Questions and Gotchas

Senior-level questions dig into edge cases and advanced Next.js features that separate experienced developers from beginners. Question: Explain Next.js middleware and provide a practical use case. Middleware runs before requests complete, letting you modify responses, redirect users, or add headers. It runs at the edge (close to users) for maximum performance. Common use cases include authentication checks, A/B testing, internationalization, and bot detection. The key insight is that middleware runs before your page code, making it perfect for request-level logic. You can redirect unauthenticated users, rewrite URLs for A/B tests, or add security headers without touching individual pages.
// File: middleware.js
// NewsWave authentication middleware
import { NextResponse } from 'next/server'

export function middleware(request) {
  const token = request.cookies.get('auth-token')
  
  // Protect admin routes
  if (request.nextUrl.pathname.startsWith('/admin')) {
    if (!token) {
      return NextResponse.redirect(new URL('/login', request.url))
    }
  }
  
  // Add security headers to all responses
  const response = NextResponse.next()
  response.headers.set('X-Frame-Options', 'DENY')
  return response
}

export const config = {
  matcher: ['/((?!api|_next/static|favicon.ico).*)']
}
Question: What are React Server Components and how do they work in Next.js 13+? Server Components render on the server and send HTML to the client, not JavaScript. They can access databases directly, use server-only libraries, and keep sensitive logic on the server. Client Components handle interactivity, state, and browser APIs. The mental model shift is crucial: Server Components are like traditional server-side templates but with React syntax. They reduce bundle size because the component code never reaches the browser. Client Components are regular React components that need the "use client" directive.
Common Interview Mistakes
• Confusing getStaticProps with getServerSideProps timing
• Not explaining the "why" behind Next.js features
• Forgetting to mention performance implications
• Missing the hybrid rendering concept
• Not knowing when to use API routes vs external APIs
Question: How would you handle a memory leak in a Next.js application? Memory leaks in Next.js usually come from client-side code — event listeners not cleaned up, timers not cleared, or subscriptions not cancelled. Use browser dev tools to profile memory usage and identify growing objects. React's useEffect cleanup functions prevent most leaks. Server-side leaks are rarer but can happen in API routes or getServerSideProps. Long-running processes, database connections not closed, or large objects staying in memory cause issues. Monitor server memory usage and implement proper cleanup. The systematic approach matters: reproduce the leak, profile memory usage, identify the growing objects, trace them back to the source code, and implement proper cleanup. Show you understand both debugging techniques and prevention strategies.

Quiz

1. Your NewsWave trending articles page needs fast loading but fresh content. When should you use Incremental Static Regeneration (ISR)?


2. What performance optimization does Next.js provide out of the box that Create React App doesn't?


3. Why shouldn't you put API keys in NEXT_PUBLIC_ environment variables?


Up Next: Mini Project – Blog

Build a complete blog application combining all the Next.js concepts you've learned, from data fetching to deployment optimization.