# 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.

- **Published:** 2026-01-09
- **Author:** Clixo
- **Reading time:** 5 min read
- **Tags:** next.js, app-router, checklist, production, performance
- **Canonical URL:** https://clixo.sh/blog/nextjs-app-router-production-checklist

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.

```mermaid
flowchart LR
  A["Architecture and Component Model"] --> B["Data Fetching"]
  B --> C["Caching"]
  C --> D["Routing and Navigation"]
  D --> E["Security"]
  E --> F["Performance"]
  F --> G["Observability"]
```

## 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](https://clixo.sh/#contact). We help product teams ship software that holds up.

---

Clixo · 1141 W Bryn Mawr Ave, Itasca, IL 60143, US · [hello@clixo.sh](mailto:hello@clixo.sh)
[Start a build](https://clixo.sh/#contact) · [All services](https://clixo.sh/services) · [Agent guide (llms.txt)](https://clixo.sh/llms.txt)
