Next.js
next/public-env-secret
Never give a secret the NEXT_PUBLIC_ prefix; those values are copied into the JavaScript every visitor downloads.
seriousstaticfe-nextjs
Why
At next build, every process.env.NEXT_PUBLIC_… reference is replaced by its value in the client bundle. A name such as NEXT_PUBLIC_STRIPE_SECRET_KEY or NEXT_PUBLIC_SUPABASE_SERVICE_ROLE therefore publishes the secret to anyone who opens the browser's developer tools, and it stays in old bundles and caches after you rotate it.
Fix
Drop the prefix and read the value only on the server: in a Server Component, a Route Handler or a Server Action, in a module that starts with import 'server-only'. Rotate the key if a build with the public name was ever deployed. Keys that are public by design (a publishable or anon key, an analytics id) may keep the prefix.
Examples
// bad
const stripe = new Stripe(process.env.NEXT_PUBLIC_STRIPE_SECRET_KEY)
// good: lib/stripe.ts
import 'server-only'
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY)Sources
Facts
- Id
next/public-env-secret- Severity
- serious
- Check
- static checked in the source by
audit - Applies to
jsx- Only in projects with
next- Taught by the skill
fe-nextjsNext.js App Router- Since version
- 0.1.0
Read it in the terminal
npx github:dawidolko/frontend-skills explain next/public-env-secret