ShipGuardScan a site

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_KEY created to make an admin query work in a client component
  • NEXT_PUBLIC_OPENAI_API_KEY used in a chat component
  • A shared config.ts that 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