The fastest way to tell if a website is vibe coded: check the URL for a default platform subdomain like .lovable.app or .vercel.app, view the page source for an unchanged template title such as Vite + React, and check the response headers for missing security headers. Three checks, under a minute.
None of those signals is proof on its own. Vibe coding — building software by describing it to an AI assistant rather than writing every line — leaves fingerprints, but plenty of hand-written sites sit on Vercel with a default favicon, and plenty of AI-assisted codebases have been reviewed line by line before shipping. What you are really detecting is a pattern: polished product surface, zero production hardening underneath.
Here are the seven signals, ordered from fastest to most conclusive, with the exact check for each.
The single fastest tell is the domain itself. AI app builders deploy to a default subdomain, and a large share of projects never move off it.
Watch for:
*.lovable.app — Lovable*.vercel.app — Vercel (the default target for v0, Cursor, and most Next.js output)*.netlify.app — Netlify*.replit.app / *.repl.co — Replit*.bolt.host — Bolt*.web.app / *.firebaseapp.com — Firebase Hosting*.pages.dev — Cloudflare PagesHow to check: look at the URL bar. If the site sits on a custom domain, resolve where it actually points:
dig +short CNAME app.example.com
# cname.vercel-dns.com. -> Vercel
# apex-loadbalancer.netlify.com. -> Netlify
Response headers work too, and they survive custom domains:
curl -sI https://example.com | grep -iE 'server|x-vercel|x-nf-request-id|x-powered-by'
A custom domain that CNAMEs to a builder platform is a strong hint. A custom domain on a generic CDN tells you nothing either way.
Builder platforms brand their free output, and template metadata is the last thing anyone remembers to change.
Look for a floating "Edit with Lovable" badge, a "Made in Bolt" chip, or a Replit ribbon — usually pinned bottom-right. Then check the details nobody edits:
<title> still reads Vite + React, Create Next App, or My Appog:image is missing entirely, so link previews render as a blank cardHow to check: press Cmd+Option+U (macOS) or Ctrl+U (Windows/Linux) to view source, then search the raw HTML for title, og:image, lovable, and bolt. A production-grade site has a written title, a real description, and a custom OG image. A vibe-coded one usually has at most one of the three.
The JavaScript bundle carries the build toolchain's signature.
How to check, step by step:
F12 or Cmd+Option+I)Then read the filenames. Vite ships hashed chunks like assets/index-a1b2c3d4.js. Next.js serves everything under /_next/static/chunks/. Create React App uses static/js/main.<hash>.js. Unchanged defaults mean nobody customized the build.
Next, search the loaded source:
Cmd+Option+F / Ctrl+Shift+F to search across all loaded filessupabase.co, firebaseio.com, and apiKeyFinding a Supabase project URL and an anon key in the bundle is normal and expected — the anon key is designed to be public, and Row Level Security is what actually protects the data. What it tells you is the stack. The genuinely alarming variants are a service_role key, a sk_live_ Stripe key, or an OpenAI key in client-side JavaScript, all of which show up in AI-generated code far more often than they should. In the DOM itself, wall-to-wall Tailwind utility classes on every element is another builder-default tell.
Read the page as a reader, not a developer. AI-drafted marketing sites converge on a recognizable shape:
lorem ipsum, "John Doe", or "Company Name" in a footer or secondary pageThis is the weakest signal here. Human marketers have shipped from the same template for a decade, and good writers use em dashes. Treat it as corroboration, never as evidence on its own.
This is where the pattern gets diagnostic. AI assistants generate features because features are what you asked for. They do not generate the invisible operational layer you did not ask for.
Security headers. In DevTools, open the Network tab, click the top-level document request, and read Response Headers. Check for Content-Security-Policy, Strict-Transport-Security, X-Content-Type-Options, X-Frame-Options, and Referrer-Policy. All five missing on a live product is a meaningful signal. securityheaders.com gives the same answer with a letter grade, or from a terminal:
curl -sI https://example.com | grep -iE 'content-security-policy|strict-transport|x-frame-options'
Default 404. Visit a URL that cannot exist — example.com/definitely-not-a-real-page. A branded 404 means someone thought about it. Vercel's stock "404: NOT_FOUND" page or a blank white screen means nobody did.
Crawl files. Fetch example.com/robots.txt and example.com/sitemap.xml. Missing or scaffold-default versions of both are routine on AI-generated sites, which is also why so many of them are invisible to search and AI answer engines.
One boundary worth respecting: passive checks on public pages are fine. Actively probing for /.env or config files on a site you do not own or have written permission to test can cross into unauthorized access. Keep the aggressive checks for your own properties.
A fully-featured product on a domain registered days ago is a timeline that used to be impossible.
How to check:
whois example.com | grep -i 'creation date'
Cross-reference two free sources: crt.sh shows the first TLS certificate issued for the domain, and the Wayback Machine shows the first crawled snapshot. A domain created last week, fronting a dashboard with auth, billing, and six feature pages, did not go through a traditional build cycle.
The caveat matters here: rebrands, domain migrations, and staging-to-production moves all produce young domains for old products. Use this to raise or lower confidence, not to conclude.
Individually, every signal above has an innocent explanation. What does not have an innocent explanation is the combination, and a security scan is what surfaces it in one pass.
The characteristic vibe-code gap profile looks like this:
allow read, write: if trueHttpOnly, Secure, or SameSiteAny one of those appears on hand-written sites. All of them at once, on a product that looks finished, is the fingerprint of code that shipped without a review pass. We break down why AI assistants produce each of these defaults in Vibe Coding Security Risks.
Not much, individually — and that is the honest framing.
A .vercel.app URL proves someone used Vercel. A missing CSP proves nobody configured one. Neither proves an AI wrote the code, and neither means the site is bad. Vibe coding is a legitimate, extremely productive way to build — plenty of strong products were drafted by an assistant and then hardened properly.
The risk is not AI-generated code. The risk is unreviewed AI-generated code reaching production. That distinction is the whole point of this list: signals 1 through 6 tell you how something was probably built, and signal 7 tells you whether it matters. A vibe-coded site with security headers, RLS enabled, and no keys in the bundle is fine. A hand-written site missing all three is not.
If the site in question is yours, the useful next step is not detection — it is hardening it.
CheckVibe's vibe coding security scanner runs the signal-7 checks from the outside, the same way an attacker would, and reports the gap pattern in one place:
robots.txt, sitemap, and metadata that keep AI-generated sites invisible to search enginesEach finding comes with a severity rating and a remediation step you can hand straight to your editor.
Run a free scan to see what a site exposes — results in under 60 seconds.
No. The signals in this guide are probabilistic, not definitive. A developer who moves off the default subdomain, replaces the favicon and title, writes original copy, and configures security headers leaves almost nothing detectable from the outside. Conversely, a hand-written site on vercel.app with a stock 404 will trip several checks. Treat the signals as confidence adjusters that stack, and never conclude from one alone.
Not inherently — but unreviewed AI output usually is. AI assistants optimize for working code, so they ship the defaults that reduce friction: wildcard CORS, no rate limiting, secrets in client code, database rules left wide open. None of that is caused by the AI being careless; it is caused by nobody asking for the security layer. A vibe-coded site that has been scanned and hardened is as secure as any other.
Look at the URL, then view the page source. A default platform subdomain such as .lovable.app or .vercel.app, combined with an unchanged template <title> or a builder badge in the corner, gets you a confident answer in about thirty seconds. If you need certainty rather than a guess, run a security scan and look for the gap pattern: exposed keys, an open backend, and missing security headers together.
Paste your URL and get a security report in 30 seconds — 100+ automated checks with AI-ready fix prompts.
Scan your site freeRelated articles
AI coding assistants ship features fast but routinely introduce security vulnerabilities. Learn the 8 most common security mistakes in vibe-coded apps and how to catch them before attackers do.
AEO for vibe-coded apps is making AI-generated sites readable and citable by ChatGPT, Claude, and Perplexity. Why AI-built apps are disproportionately invisible — and the exact fixes.
Client-only SPAs are invisible to AI crawlers. The exact steps to make a vibe-coded React SPA rank in ChatGPT, Perplexity, and Claude: prerendering, robots.txt, llms.txt, schema, answer-first content.