NEXT_PUBLIC_ Pitfalls in AI-Generated Next.js Apps
Updated 2026-10-17
NEXT_PUBLIC_ is a build-time instruction: inline this value into JavaScript sent to browsers. It is correct for analytics IDs and publishable keys, and wrong for anything that grants access.
Patterns that leak
Watch for these in AI-written code and pull requests:
NEXT_PUBLIC_SUPABASE_SERVICE_ROLE_KEYcreated to make an admin query work in a client componentNEXT_PUBLIC_OPENAI_API_KEYused in a chat component- A shared
config.tsthat reads both public and secret values, imported by a client component - Secrets passed as props from a server component into a client component
Safer alternatives
Use route handlers or server actions for privileged work, keep secret config behind import "server-only", and pass only derived, non-sensitive data to client components.
Checklist
- Every NEXT_PUBLIC_ value reviewed
- No secrets passed as client props
- server-only guard on secret config
- Rotated anything that was ever public
Copy-paste fix prompt
List all NEXT_PUBLIC_ variables and classify each as safe-public or secret. For secret ones, remove the prefix, move usage server-side, and make sure no server component passes the value as a prop to a client component.FAQ
Can I read process.env.SECRET in a client component without the prefix?
It will be undefined in the browser. That is the protection working; fetch the data through the server instead of adding the prefix.
Are values in server component props safe?
Props passed to client components are serialized into the page. Never pass secrets that way.
Check your deployed app in ~25 seconds
Free passive scan: leaked keys, Supabase exposure, public config files and headers.
Run a free scan