Key Concepts

+ Add Concept
Next.js Parallel and Intercepting Routes

Next.js Parallel and Intercepting Routes

Next.js provides advanced routing mechanisms to handle complex UI requirements.

Parallel Routes

Allow you to simultaneously or conditionally render one or more pages in the same layout. They are defined using “slots” (e.g., @team and @analytics).

  • Use Case: Dashboards with independent sections, split-screen views.

Intercepting Routes

Allow you to load a route from another part of your application within the current layout.

  • Convention: (.) to match segments on the same level, (..) for one level above, etc.
  • Use Case: “Modals” where clicking an image opens it in a modal over the current page, but refreshing the page loads the image on its own page.
Next.js App Router

Next.js App Router

The App Router is the modern system for building Next.js applications, introduced in Next.js 13 and becoming the default in Next.js 14 and 15. It is built on React’s latest features, including Server Components and Streaming.

Key Features

  • Server Components: Components that run on the server and reduce the amount of JavaScript sent to the client.
  • File-based Routing: Routes are defined by folders, with page.js files acting as the entry point.
  • Nested Layouts: Easily share UI between routes using layout.js.
  • Streaming: The ability to send chunks of the UI to the client as they are generated.
Authentication Patterns

Next.js Authentication Patterns

Authentication in Next.js (especially the App Router) revolves around where the session is stored and how it is accessed.

Session Strategies

  1. Server-side Sessions (HTTP-only Cookies): The preferred method for security. Sessions are read in Middleware, Server Components, and Route Handlers.
  2. Client-side Sessions (JWT in LocalStorage): Less secure and generally discouraged in modern Next.js apps as they can’t be accessed by Server Components during pre-rendering.

Protection Mechanisms

  • Middleware: The first line of defense. Used to redirect unauthenticated users before they even reach a page.
  • Server Components: Checking for a session directly using cookies() or a library like Auth.js to conditionally render content.
  • Route Handlers/Actions: Validating the session before performing any sensitive mutations.
Next.js Caching Mechanisms

Next.js Caching Mechanisms

Next.js provides four distinct caching layers to optimize application performance and reduce costs.

1. Request Memoization

React extends the fetch API to automatically memoize requests with the same URL and options. This lasts for the duration of a single render pass on the server.

2. Data Cache

Stores data across user requests and deployments. It is a persistent cache on the server. You can control this via revalidate or cache: 'force-cache'.

3. Full Route Cache

Next.js automatically caches the rendered output (HTML and RSC payload) of a route at build time or during revalidation. This reduces server work for static routes.

4. Router Cache (Client-side)

An in-memory cache that stores the RSC payload of visited and prefetched segments in the browser, lasting for the duration of a user session.

Next.js Draft Mode

Next.js Draft Mode

Draft Mode allows you to preview content from your Headless CMS in real-time, even if the pages are normally statically generated (SSG).

How it Works

  1. Enable: You create a Route Handler that calls draftMode().enable(). This sets a secure cookie in the browser.
  2. Bypass Cache: When the cookie is present, Next.js bypasses the Full Route Cache and the Data Cache for fetch requests, ensuring the latest content is fetched from the CMS.
  3. Disable: You can call draftMode().disable() to clear the cookie and return to normal cached behavior.

Use Case

Content editors want to see how a blog post looks on the live site before hitting “Publish.” Draft Mode enables this without making the site dynamic for all users.

Next.js Error Handling

Next.js Error Handling

Next.js provides a robust error-handling system using special files that allow you to define UI for different error scenarios.

Special Files

  • error.js: Defines an error boundary for a specific segment and its children. It must be a Client Component.
  • global-error.js: A specialized error boundary for the root layout, used to catch errors in the entire application.
  • not-found.js: Used to render a UI when the notFound() function is called or when a route doesn’t match.
  • loading.js: While primarily for streaming, it also handles the “loading” state during data fetching.

How it works

When an error occurs in a component, Next.js will bubble it up to the nearest error.js boundary. This allows the rest of the application to remain functional while the specific segment shows a fallback UI.

Next.js Font and Script Optimization

Next.js Font and Script Optimization

Next.js provides built-in components to optimize the loading of fonts and scripts.

Next Font (next/font)

Automatically optimizes your fonts (including custom fonts) and removes external network requests for improved privacy and performance.

  • Zero Layout Shift: Automatically calculates the size of the font to prevent CLS.
  • Self-hosting: Google Fonts are downloaded at build time and hosted with your deployment.

Next Script (next/script)

The Script component enables you to set the loading priority of third-party scripts.

  • beforeInteractive: Load before any Next.js code and before page hydration.
  • afterInteractive: (Default) Load immediately after page hydration.
  • lazyOnload: Load during idle time.
  • worker: (Experimental) Load in a web worker.
Forms and Validation

Next.js Forms and Validation

Next.js leverages Server Actions and React’s specialized hooks to provide a seamless form-handling experience.

Key Components

  • Server Actions: Handle the backend logic of the form submission.
  • useActionState (formerly useFormState): Manages the state of the form (e.g., success message, validation errors) returned from the action.
  • useFormStatus: Provides the pending state of the submission for UI feedback (like loading spinners).
  • Zod: Often used alongside Server Actions to validate FormData on the server before processing.
  • Progressive Enhancement: Forms can work with standard HTML <form action="..."> even before JavaScript has loaded.
Next.js Internationalization (i18n)

Next.js Internationalization (i18n)

Next.js allows you to configure routing and rendering of content to support multiple languages.

Routing Strategy

In the App Router, i18n is typically implemented using dynamic route segments. A common pattern is putting all routes inside a [lang] folder (e.g., app/[lang]/page.tsx).

Key Components

  • Middleware: Used to detect the user’s preferred language (via the Accept-Language header or a cookie) and redirect them to the appropriate localized route.
  • Dictionaries: JSON files containing translations for each language, which are loaded as needed in Server Components.
  • Static Generation: Using generateStaticParams to pre-render all pages for all supported languages.
Next.js Image Optimization

Next.js Image Optimization

The next/image component extends the HTML <img> element with features to help you achieve good Core Web Vitals, specifically Largest Contentful Paint (LCP) and Cumulative Layout Shift (CLS).

Key Features

  • Size Optimization: Automatically serves correctly sized images for each device using modern formats like WebP and AVIF.
  • Visual Stability: Prevents layout shift automatically by requiring dimensions or using fill.
  • Faster Page Loads: Images are only loaded when they enter the viewport using native browser lazy loading, with optional blur-up placeholders.
  • Asset Flexibility: On-demand image resizing, even for images stored on remote servers.
Instrumentation and Monitoring

Next.js Instrumentation and Monitoring

Instrumentation is the process of using code to integrate monitoring and logging tools into your application.

The instrumentation.ts File

Next.js provides a special instrumentation.ts file in the root directory (or src/) that runs once when a new Next.js server instance is started. This is the place to:

  • Initialize monitoring tools (Sentry, New Relic, etc.).
  • Configure OpenTelemetry (OTEL) for distributed tracing.
  • Run any necessary side effects on server startup.

OpenTelemetry

Next.js has built-in support for OpenTelemetry, allowing you to export spans and traces to observability platforms. This helps in debugging slow database queries or API calls across different services.

Next.js Metadata API

Next.js Metadata API

The Metadata API allows you to define metadata (e.g. meta and link tags inside your HTML head element) using a declarative object in your layouts or pages.

Key Features

  • Static Metadata: Export a metadata object from a layout or page.
  • Dynamic Metadata: Export a generateMetadata function to fetch metadata based on dynamic parameters.
  • Inheritance: Metadata is automatically merged from parent layouts to child pages, following a specific evaluation order.
  • File-based Metadata: Support for special files like favicon.ico, opengraph-image.png, and sitemap.xml.
Next.js Middleware

Next.js Middleware

Middleware allows you to run code before a request is completed. Based on the incoming request, you can modify the response by rewriting, redirecting, modifying the request or response headers, or responding directly.

Key Characteristics

  • Edge Runtime: Middleware runs on the Edge, making it extremely fast and low-latency.
  • Filtering: You can use a matcher to limit Middleware to specific paths.
  • Use Cases: Authentication, Bot protection, A/B testing, Redirects, and Localization.
Next.js Rendering Strategies

Next.js Rendering Strategies

Next.js provides several ways to render your content, each with different performance characteristics and use cases.

Static Site Generation (SSG)

Next.js generates the HTML at build time. The pre-rendered HTML is then reused on each request. It can be cached by a CDN.

  • Use case: Marketing pages, blog posts, documentation.

Server-Side Rendering (SSR)

Next.js generates the HTML on each request.

  • Use case: Pages with highly dynamic data or user-specific content.

Incremental Static Regeneration (ISR)

Enables you to use static generation on a per-page basis without needing to rebuild the entire site.

  • Use case: Large scale sites with frequently updated data.
Next.js Route Handlers

Next.js Route Handlers

Route Handlers allow you to create custom request handlers for a given route using the Web Request and Response APIs. They are the App Router’s equivalent of API Routes.

Key Characteristics

  • File-based: Defined in route.ts or route.js files.
  • HTTP Methods: Supported methods include GET, POST, PUT, PATCH, DELETE, HEAD, and OPTIONS.
  • Edge & Node.js Runtimes: Can run in either runtime, depending on configuration.
  • Caching: GET requests are cached by default unless they use dynamic functions (like cookies()) or are explicitly opted out.
  • Conflict: A route.ts file cannot exist in the same folder as a page.ts file.
Next.js Security and Secrets

Next.js Security and Secrets

Next.js provides built-in mechanisms to prevent accidental data leaks and protect your application.

Environment Variables

  • Private: Variables in .env are only available in the Node.js environment (Server Components, Route Handlers).
  • Public: Variables prefixed with NEXT_PUBLIC_ are bundled into the JavaScript sent to the browser.

Data Tainting (Experimental)

The Taint API (experimental_taintObjectReference and experimental_taintUniqueValue) allows you to mark specific objects or values as “private,” preventing them from being passed to a Client Component.

Server Actions Security

Server Actions are protected from CSRF by default. However, developers must still implement Authorization within the action itself to ensure the current user has permission to perform the task.

Next.js Server Actions

Next.js Server Actions

Server Actions are asynchronous functions that are executed on the server. Introduced in Next.js 13.4 and stabilized in Next.js 14, they can be used in both Server and Client Components to handle form submissions and data mutations in Next.js applications.

Key Benefits

  • Zero Client JavaScript: When used with forms, they can work without client-side JS (Progressive Enhancement).
  • Reduced Boilerplate: No need to manually create API routes for simple mutations.
  • Type Safety: Integrated with TypeScript for end-to-end type safety between the form and the server.
  • Cache Integration: Works seamlessly with revalidatePath and revalidateTag to update the data cache.
Static vs. Dynamic Rendering

Static vs. Dynamic Rendering

Next.js automatically determines if a route is Static or Dynamic based on the features and data-fetching methods used.

Static Rendering

Next.js renders the route at build time, or in the background after data revalidation. The result is cached and can be pushed to a CDN. This is the default behavior.

Dynamic Rendering

Next.js renders the route for each user at request time. This is necessary when the route has data that is unique to the user or only known at the time of the request (e.g., cookies, URL search parameters).

Switching to Dynamic Rendering

A route will switch to dynamic rendering if:

  • Dynamic Functions are used: cookies(), headers(), or searchParams in a page.
  • Uncached Data Requests are used: fetch with cache: 'no-store' or revalidate: 0.
  • Segment Config Options are set: export const dynamic = 'force-dynamic'.
Next.js Streaming and Suspense

Next.js Streaming and Suspense

Streaming allows you to break down the page’s HTML into smaller chunks and progressively send them from the server to the client. This is powered by React Suspense.

Key Benefits

  • Faster TTFB (Time to First Byte): The server can start sending the layout and non-dynamic parts of the page immediately while the data-heavy components are still fetching.
  • Parallel Data Fetching: Different parts of the page can load independently. A slow API call in one component won’t block the rest of the page from being interactive.
  • Improved UX: Instead of a blank screen or a full-page spinner, users see the navigation and layout immediately, with specific loading states (skeletons) where data is missing.

Implementation

  • loading.js: A special file that automatically wraps a page or segment in a Suspense boundary.
  • Manual <Suspense>: For more granular control within a page, wrapping specific components.

Questions (20)