How do you add lead attribution to a vibe-coded site?

To add lead attribution to a site built with Lovable, v0, Bolt or Cursor, make every form save the visitor's UTM parameters and click IDs with the submission. AI builders generate forms that send the visible fields only, so you either prompt for hidden fields plus a storage script, or install a tracking snippet that adds them.

  1. Check what your form actually sends today.
  2. Add hidden UTM fields and a script that stores UTMs on arrival.
  3. Make the backend save those fields.
  4. Test with a tagged URL before launch.

A tagged link lands on the AI-built page, the UTMs are stored in a cookie, the form sends them to your database or CRM, and you can see leads by source.

Vibe coding means building software by describing it to an AI tool and accepting what it generates, rather than writing most of the code yourself. For the bigger picture of turning an AI-built site into revenue, see what to do after you build your AI-built website.

Why AI-built forms drop the lead source

The AI did exactly what you asked. You asked for a contact form, so you got name, email and message, posted to Supabase, a serverless function or an email service. Nobody asked for the source.

Three things go missing:

  • No hidden fields. The form only sends what's visible.
  • No persistence. Single-page apps change routes without reloading, and UTMs on the first URL disappear after the first navigation.
  • No storage. Even if the values are sent, the table or email template has no column for them.

Lovable contact forms: where the source gets lost

A Lovable contact form is usually a React component that posts to one of three places: a Supabase table, an edge function that sends an email, or a form backend such as Formspree. Each one stores exactly the fields the form sends, and nothing more.

Lovable form posts toWhat to add so the lead keeps its source
Supabase tableHidden inputs plus utm_source, utm_medium, utm_campaign columns in the table
Edge function or emailHidden inputs, and the function must include them in the row or email it sends
FormspreeHidden inputs only. Formspree stores every named field it receives, so the UTMs appear on each submission

Formspree with Lovable is the simplest case: add hidden inputs named after each UTM, fill them from a stored cookie, and they arrive in Formspree alongside name and email. Check Formspree's docs for the current field handling. Trakt works with all AI-built sites, so its snippet adds the hidden UTM fields to Lovable forms whichever backend they post to.

Prompt your AI builder to add hidden UTM fields

Paste something like this into Lovable, v0, Bolt or Cursor. Adjust the table name.

Add lead source tracking to every form on this site.
1. On first page load, read utm_source, utm_medium, utm_campaign, utm_term,
   utm_content, gclid and fbclid from the URL and save them in a first-party
   cookie for 90 days. Do not overwrite saved values with empty ones.
2. Also save the landing page path and document.referrer on first visit.
3. Add hidden inputs for all of these to every form, filled from the cookie.
4. Send them with the submission and add matching columns to the leads table.
5. Only set the cookie after the visitor accepts analytics cookies, if a
   consent banner exists.

Review what it generates. Check the columns exist and that the cookie is set before any redirect. Capturing UTM parameters in hidden fields has a reference script to compare against.

When the manual version works, keep it, or pre-register for Trakt and let the snippet maintain the hidden fields as your AI keeps rewriting the site.

How Trakt handles it on AI-built sites

Paste the Trakt snippet into your site's head once. It saves UTMs and click IDs in a first-party cookie, injects hidden UTM fields into your forms automatically and fills them, and records each submission with its source attached. Regenerated pages and new forms are covered because the snippet runs on every page. You can also build the form in Trakt instead.

Test checklist before launch

CheckHowPass looks like
UTMs survive navigationOpen ?utm_source=test, click two pages, submitLead shows source "test"
Click IDs capturedOpen ?gclid=abc123, submitLead shows the gclid
Backend stores themLook at the database row or CRM recordColumns filled, not blank
Consent respectedDecline cookies, submitNo tracking cookie set
Mobile in-app browserTap a tagged link inside Instagram or TikTokSource still recorded
Redirects keep the queryHit http:// and non-www versionsTags still on the final URL

Run the free attribution audit on the live URL too. It flags missing form capture, broken redirects and consent issues.

Why prompt-built tracking breaks in practice (and how Trakt helps)

AI builders rewrite files freely. The next "make the hero nicer" prompt can drop your hidden inputs or the cookie script, and you won't see it until leads arrive as Direct.

How Trakt closes the gap

Trakt works with all AI-built sites. The snippet injects and fills hidden fields on every form, so regenerated pages stay tracked. Each lead keeps its first touch, visits are linked across devices, source and revenue sync into your CRM, and new leads alert you by email and Slack. The dashboard shows leads by source.

Prompted tracking vs. Trakt, by requirement

RequirementPrompted codeTrakt
Hidden UTM fieldsGenerated per formInjected automatically
Survives regenerationNot guaranteedYes, snippet runs on every page
Consent handlingWhatever you promptConsent Mode v2, OneTrust, Cookiebot
Source and revenue in CRMBuild itSynced
Tagging your campaign linksSame either waySame either way

FAQ

How do I track form submissions on a Lovable site?

Add hidden UTM fields to the form, a script that saves UTMs in a cookie on the first page, and columns in your database to store them. Or install a tracking snippet such as Trakt's, which injects and fills the hidden fields for you.

Why do leads from my AI-built site show no source?

AI builders create forms that send the visible fields only. Without hidden fields and a cookie to hold the UTMs across page changes, the submission has nothing to say where the visitor came from.

Can I prompt v0 or Bolt to add UTM tracking?

Yes. Ask for UTMs and click IDs to be saved in a first-party cookie on first load, hidden inputs on every form filled from it, and matching database columns. Review the code and test with a tagged URL.

Does Trakt work with Cursor or Lovable sites?

Yes. Trakt works with all AI-built sites. You add the snippet once, and it captures the source on every form, including forms the AI adds later.

How do I test tracking on a vibe-coded site before launch?

Open the site with a test UTM, navigate to another page, submit the form and check the stored record. Repeat for click IDs, a declined consent banner and a phone in-app browser, then run an attribution audit on the live URL.

What to do first

Open your live site with ?utm_source=test, click once, and submit your own form. Then open the database row. If the source column doesn't exist, start there: no prompt can fill a column that isn't in the table.