TL;DR: v0.dev writes clean React and Next.js UI fast. It does not guard your keys, set your headers, or draw the server/client line for you. Two traps are v0-specific. Secrets in NEXT_PUBLIC_ env vars, which ship to every browser. And private logic inside client components, where anyone can read it. This guide covers both, plus headers on Vercel — or scan your live app free in about 30 seconds first.
v0 is Vercel's AI UI tool. You type a prompt. It hands back a working UI wired to your data. The speed is the pitch. It is also the trap, because a working demo and a safe app are two different things. v0.dev security is the gap between them.
The NEXT_PUBLIC_ leak: Next.js's version of the VITE_ trap
Every AI stack has one env-var rule that bites founders. In Vite apps — Lovable and Bolt builds — it is the VITE_ prefix. In Next.js and v0, it is NEXT_PUBLIC_. The rule is simple. Any env var that starts with NEXT_PUBLIC_ gets baked into the JavaScript bundle sent to every browser.
That is by design. It is how you pass safe, public config to the frontend. The trap is what the AI does under time pressure. A prompt needs a key to work. The fastest fix is NEXT_PUBLIC_API_KEY. The demo works. The key is now public. Anyone can view source, open the bundle, and read it in plain text.
Here is the line that matters:
| Env var | Where it ends up | Safe for |
|---|---|---|
NEXT_PUBLIC_SUPABASE_URL | Client bundle (public) | Fine — it is meant to be public |
NEXT_PUBLIC_SUPABASE_ANON_KEY | Client bundle (public) | Fine — if RLS is on and policies are real |
NEXT_PUBLIC_STRIPE_SECRET | Client bundle (public) | Never. This is a published secret. |
SUPABASE_SERVICE_ROLE_KEY | Server only | Server components, API routes, server actions |
STRIPE_SECRET_KEY | Server only | Server routes that talk to Stripe |
Two notes on that table. The anon key is only safe if Row Level Security is on with owner-scoped policies — CVE-2025-48757 hit 170+ AI-built apps that skipped that step. And if you are not sure which Supabase key is which, read anon key vs service role key before you ship. To hunt leaked keys in your own bundle, our guide on finding exposed secrets in AI bundles walks through it step by step.
Server components vs client components: the trust line
Next.js splits your app into two worlds. Server components run on Vercel's servers. Their code never reaches the browser. Client components — anything marked "use client" — run in the user's browser. Everything inside them is readable: the logic, the comments, the hardcoded values.
That split is a trust line. v0 does not always respect it. To make a demo work, it will put a data call or a business rule in client code. It runs. It also shows every visitor how your app thinks, and sometimes hands them a token to act on it.
The rule is short. Secrets, database calls, and pricing or permission logic live server-side — in server code, API routes, or server actions. The browser gets rendered results, never the recipe. When you review v0 output, search for "use client" and ask one question per file: does anything in here need to stay private? If yes, move it.
Headers on Vercel: TLS is not the same as hardened
Vercel gives every deploy TLS out of the box. That is transport, not defense. The headers that guard your users — CSP, HSTS, X-Frame-Options, X-Content-Type-Options — are not set unless you set them. Nothing breaks without them. The app runs fine. What you lose is the browser-side layer that keeps a script attack from turning into account takeover.
You add them in one of three places: a headers() block in next.config.js, a middleware file, or vercel.json. It is about twenty lines. Test your live domain in seconds with the free security headers checker to see what is missing right now.
The gaps v0 shares with every AI builder
The rest of the v0 checklist matches what we find across all tools — see the full AI coding platform security comparison for the tool-by-tool view.
- No rate limits. API routes and server actions ship open. Our k6 engine reports it word for word as
"No rate limiting detected under concurrent load."(k6Scanner.js:170). Probe an endpoint with the API rate limit checker. - Open database rules. If your v0 frontend talks to Supabase, check RLS with the free Supabase RLS checker.
- No input checks. Forms write to your backend with whatever the visitor typed.
- No error tracking. The first person to find a production bug is a user.
The pattern is well measured. Symbiotic Security scanned 1,072 AI-built apps. 98% had at least one flaw. 16% had critical issues. CMU's SusVibes study found 61% of AI-written code carried at least one security flaw. Our own 100-app pool averages 42/100. One more note for v0 users: researchers have shown attackers using v0 itself to spin up fake login pages in minutes. The same speed you love, pointed at your users. One more reason your real app should look solid: headers set, domains clean, nothing leaking.
One compliance note before launch
v0 builds the form that collects the email. It does not build the privacy layer around it. GDPR follows your users, not your office. And if your app has an AI-facing feature and EU users, the EU AI Act's transparency rules (Article 50) apply from August 2, 2026. Users must be told they are talking to an AI. Fines for that breach run up to €15 million or 3% of global turnover. Our Compliance Wing checks both layers in one pass.
Your v0 pre-launch checklist
- List every
NEXT_PUBLIC_var. If one holds a secret, move it to a server-only var and rotate the key. - Search for
"use client". Move secrets, data calls, and private logic server-side. - Turn on RLS for every table. Owner-scoped policies. No
USING (true). - Set CSP, HSTS, X-Frame-Options, and X-Content-Type-Options on your deploy.
- Rate-limit API routes and server actions.
- Add error tracking so you hear about failures before users do.
- Turn off debug output and source maps in production.
- Re-scan after every fix. Fixes interact.
What an audit costs
The free scan is $0. It scores your live app out of 100 across security, reliability, performance, and monitoring. It takes about 30 seconds. The full Launch Readiness Audit is $499 one time — a branded report, a ranked fix plan with time costs, and a benchmark against 200+ audited apps. Monitoring plans run $149 to $599 a month. Want the fixes done for you? Done-for-you setup is $1,999 with a named CTO. Start with the scan. It tells you if you need more.
FAQ
Is v0.dev safe to build with?
Yes. v0 is Vercel's AI UI builder, and the tool itself is fine. The risk sits in what you ship: keys in NEXT_PUBLIC_ vars, sensitive logic in client components, no rate limits, and no security headers. Those need their own check before launch.
What is the NEXT_PUBLIC_ leak?
In Next.js, any env var that starts with NEXT_PUBLIC_ is bundled into the JavaScript sent to every browser. Put a secret key in one and you have published it. It is the Next.js version of the VITE_ leak in Vite apps. Real secrets belong in server-only vars.
Why do server vs client components matter for security?
Server components run on the server and never ship their code to the browser. Client components run in the browser, where anyone can read them. Secrets, database calls, and business rules belong server-side. v0 often blurs that line to make a demo work.
Does Vercel add security headers for me?
No. Vercel serves your app over TLS, but CSP, HSTS, X-Frame-Options, and X-Content-Type-Options are not set by default. You add them in next.config.js, in middleware, or in vercel.json. Until then, that browser-level defense layer is off.
How do I check my v0 app without sharing code?
Run a URL-based scan. It tests your live app from the outside, the same way an attacker starts: bundle contents, headers, rate limits, and exposed paths. Launch Ready Code's free scan takes about 30 seconds and scores your app out of 100.
What does a v0.dev security audit cost?
The scan is free. The full Launch Readiness Audit is $499 one time: a branded report, a ranked fix plan, and a benchmark against 200+ audited apps. Monitoring plans run $149 to $599 a month. Done-for-you setup is $1,999 with a named CTO.
v0 got you a real interface in an afternoon. The last mile is a short list: clean vars, a clear server line, real headers, real limits. Run the list, then launch loud.
See what your v0 app ships to every browser
One URL. About 30 seconds. A score out of 100 and the exact gaps to fix before someone else finds them.
Run the free scan — $0