WritingNext.js App Router Production Readiness Checklist — Clixo
5 min readnext.js, app-router, checklist, production, performance

Next.js App Router Production Readiness Checklist

A 25-point checklist to make your Next.js App Router application production-ready — covering performance, security, caching, error handling, and observability.

Shipping a Next.js application is easy. Shipping one that stays healthy under real traffic, handles failures gracefully, and gives your team visibility into what is happening — that takes deliberate setup. Most teams discover the gaps only after something breaks in production.

This checklist covers the decisions and configurations that separate a prototype from a production-grade Next.js App Router application. Work through it before your first public launch, and revisit it before each major release.

Architecture and Component Model

  • Server components are the default. Every component that does not need browser APIs or local state should be a server component. use client should appear only at leaf nodes.
  • use client boundaries are as narrow as possible. If only a button is interactive, the button file gets use client — not the page or section wrapping it.
  • Server-only code is enforced. Import server-only in any module that accesses secrets, the database, or the filesystem to prevent accidental client-side exposure.
  • No secrets are passed as props to client components. Only sanitized, presentation-safe data crosses the server-to-client boundary.

Data Fetching

  • Parallel fetches use Promise.all. Independent await calls in the same component are grouped so their latencies do not stack.
  • Slow data sources are wrapped in Suspense. Users see partial content immediately; slower sections stream in without blocking initial HTML.
  • generateStaticParams is configured for dynamic routes. Known slugs are pre-rendered at build time rather than generated on every request.
  • Database queries use connection pooling. Serverless environments open many connections. A pooler like PgBouncer or a serverless-optimized client prevents exhausting the connection limit.

Caching

  • Each data source has an explicit cache policy. No fetch call relies on the default behavior without the team understanding what that default is.
  • Tag-based revalidation is wired to mutations. Server Actions that write to the database call revalidateTag so stale cached data is invalidated immediately.
  • cache: 'no-store' is used sparingly and intentionally. Disabling caching on a fetch that does not change per-request is waste; confirm the reason before opting out.
  • Sensitive personalized data is not cached. Cache keys that could collide across users do not cache user-specific responses.

Routing and Navigation

  • Route groups organize shared layouts. Folders wrapped in parentheses group related routes under a shared layout without polluting the URL.
  • not-found.tsx and error.tsx exist at appropriate levels. Every route segment with data fetching has error and not-found boundaries so failures show a recovery UI rather than a blank or broken page.
  • loading.tsx shows meaningful skeletons. Loading states match the shape of the content that replaces them, reducing layout shift.
  • Middleware matchers exclude static assets. The middleware matcher pattern does not run auth or analytics logic on /_next/static/, /favicon.ico, or image files.

Security

  • All form mutations go through Server Actions with input validation. No user input is trusted before parsing and validation on the server.
  • Rate limiting is applied to sensitive endpoints. Login forms, signup flows, and mutation endpoints have rate limits enforced at the middleware or edge layer.
  • Content-Security-Policy headers are configured. Next.js supports setting security headers in next.config.js under headers. CSP, X-Frame-Options, and Referrer-Policy are set.
  • Environment variables are audited. Variables prefixed with NEXT_PUBLIC_ are visible in the browser. Secrets use unprefixed names and are never exposed to the client.

Performance

  • Images use next/image. All img tags are replaced with the Image component to enable lazy loading, responsive sizing, and format optimization.
  • Fonts use next/font. Local or Google Fonts are loaded through next/font to eliminate layout shift and external font requests.
  • Bundle analyzer has been run. @next/bundle-analyzer is used at least once before launch to identify unexpectedly large client-side dependencies.
  • Core Web Vitals are measured before launch. LCP, CLS, and INP are checked in a production build using Lighthouse or a real-user monitoring tool. Known regressions are addressed before users see them.

Observability

  • Structured logging is in place. Application errors and key events write to a log aggregation service, not just console.log.
  • Error tracking captures server-side exceptions. A tool like Sentry is configured to capture both server component errors and client-side exceptions.
  • Uptime monitoring alerts before users notice. A synthetic monitor pings key routes and alerts when response times degrade or status codes change.

No checklist covers every application's unique requirements, but these twenty-five items address the most common gaps between a working prototype and a production-grade system.

If your team is preparing a Next.js application for launch and wants experienced engineers to review the architecture before go-live, talk to Clixo. We help product teams ship software that holds up.