Know where the security boundary is
In the App Router, the boundary is the server: server actions and route handlers. Client components are not a security layer - anything they enforce, a user can bypass. Generated code often puts the check in the wrong place.
- Authorize inside server actions and handlers
Per-record ownership checks, executed server-side, on every mutation and sensitive read.
- Don't trust middleware alone for authz
Middleware is good for coarse routing/redirects; enforce real authorization in the handler that touches data.
- Validate inputs at the server boundary
Schema-validate everything a server action or handler receives.
Secrets, env, and the client bundle
Next.js inlines any environment variable prefixed for the client into the browser bundle. The classic leak is a secret given a public prefix, or a key referenced in a client component.
- Keep secrets unprefixed and server-only
Only genuinely public values get the public env prefix.
- Verify auth on protected pages server-side
A real session check in a server component or handler, not a client-side redirect.
Caching, scale, and cost
Next.js caching is powerful and easy to get subtly wrong - over-caching leaks stale or per-user data, under-caching hammers your database and bill. Generated apps rarely make a deliberate caching choice.
Pair that with the usual data-access review: N+1 queries in server components, unbounded reads, and missing indexes. And price your hot paths - server-rendered pages that fan out to multiple services on every request are a common cost surprise.
The pre-launch checklist
- Authorize per record inside server actions/handlers
The server is the boundary, not the client.
- Schema-validate all server inputs
Reject malformed payloads at the boundary.
- Audit client-prefixed env vars for secrets
Keep sensitive values server-only and rotate leaks.
- Enforce server-side session checks on protected routes
No client-only redirects for access control.
- Make a deliberate caching choice per route
Avoid leaking per-user data or hammering the database.
- Remove N+1 / unbounded queries in server components
Keep server rendering fast under data volume.
- Price server-rendered hot paths
Watch requests that fan out to many services.
Run this checklist on your repo, automatically
PeakStack scores every commit for security, scalability, and cost - with the exact line and a fix.
Request accessFAQ
What's the most common Next.js production mistake in AI-built apps?
Putting the security check in the wrong place - relying on client components or middleware for authorization instead of enforcing per-record ownership inside the server action or route handler that touches data.
How do secrets leak in a Next.js app?
Through environment variables given the public client prefix, or keys referenced in client components - both get inlined into the browser bundle. Keep secrets unprefixed and server-only, and rotate anything exposed.
How do I keep a Next.js app production-ready as it grows?
PeakStack reviews every commit for security, scalability, and cost - flagging misplaced authorization, exposed secrets, unsafe queries, and risky caching with the exact line and a fix.