blog · 5 September 2026 · 8 min read

How to add a cookie banner to a Lovable app that actually blocks trackers

Lovable ships your app without a cookie banner, and asking it for one gets you a box that blocks nothing. Here is the ten-minute route to a banner that holds every tracker until people agree, with the checks that prove it.

What Lovable ships, and what it does not

A Lovable project is a standard Vite and React app: an index.html at the root, a src/ folder the agent rewrites as you prompt, and, if you turned it on, a Supabase backend for auth and data. When you publish, the app goes to your-project.lovable.app, or to your own domain once you connect one.

Three things arrive with that app that have consent consequences. First, Lovable’s own visitor analytics. The docs say it is on by default, that it tracks visitors, page views, bounce rate, visit duration, traffic sources and devices, and that it “measures overall traffic, not individual people”. They do not say what, if anything, it stores in the visitor’s browser. Second, whatever you prompted for: “Add Google Analytics” puts the GA4 snippet in the head, “Add the Meta pixel” does the same for Facebook. Third, embeds: a YouTube video or a Google Map inside a component sets cookies the moment the iframe loads.

What does not arrive is anything that holds those scripts back until a visitor decides. And if you prompt “add a GDPR cookie banner”, Lovable does what any coding agent does: it writes a nice React component with an Accept button that sets a flag in localStorage and blocks nothing. That is the banner the CNIL fined SHEIN €150 million for in September 2025, in a prettier font. This post is the alternative, and it takes about ten minutes.

Where the tag goes

A Lovable project is a Vite and React app with index.html at the root. The consent tag is the first thing in its head, and most prompts never touch that file, so it survives regeneration.

The consent runtime is a single script tag, and it has to be the first element inside <head> in index.html. Not in App.tsx, not in a useEffect, not in a layout component. Two reasons. The runtime installs its interceptor synchronously, so anything that runs before it can set a cookie the runtime cannot take back. And index.html is the one file a Lovable prompt almost never rewrites, so the tag survives the next fifty iterations on your landing page.

Step 1: get a key

Create a free account, add a site, and enter the domain your app is published on. If you have not connected a custom domain yet, that is the lovable.app address; you can change it later without touching the tag. Open Install and copy the production key. Each site also has a preview key, which serves whatever you published to preview and is the one to use on Lovable’s preview URL while you test.

Step 2: the prompt

On the free plan Lovable’s Code tab is read-only, so the agent does the edit. On a paid plan you can open index.html in the Code tab and paste the tag yourself, and with GitHub sync on you can do it in your own editor and push. Whichever route, the instruction is the same, and the important part is what it forbids.

Paste into Lovable
Add this script tag as the very first element inside <head> of index.html, unchanged:

<script src="https://app.cookiecrumbs.eu/runtime/cc.js"
        data-cc-site="pk_live_…"
        data-cc-env="production"></script>

Then, for every analytics, advertising or social script already in index.html (Google Analytics, gtag, Meta Pixel, TikTok, Hotjar, Clarity), change type to "text/plain" and add data-cc-category="analytics" or data-cc-category="marketing". Do not build a cookie banner component. Do not change anything else.

Read the diff before you accept it. It should add four lines at the top of index.html and change the type attribute on your tracking scripts. If the agent also creates a CookieBanner.tsx, reject the change and repeat the last sentence of the prompt. Then publish.

Step 3: sort what the app loads

Everything a Lovable app tends to load, who put it there, and the category it belongs to. Only the first row is outside your code, which is why you scan before you trust it.

In the dashboard, run the first scan. It opens your published app in a real browser three times, with consent denied, granted per category and granted for everything, and lists every request and cookie that appeared before a choice. That list is the truth about your app, whatever the prompt history says.

Most of what it finds sorts itself: GA4, Hotjar and Clarity are analytics; the Meta pixel, TikTok and LinkedIn tags are marketing; the Supabase session lives in localStorage, is strictly necessary for a logged-in app and needs no consent. Embedded YouTube and Maps iframes are marketing, and the runtime replaces them with a placeholder and a “Cookie settings” button until the category is granted.

The one row you cannot gate with a tag is Lovable’s own visitor analytics, because Lovable’s hosting adds it outside your code. If the scan shows it storing an identifier in the browser, or calling a third party, you have two honest options: turn it off under Project settings, General, Publishing, or list it in your cookie declaration and treat it as analytics that loads before consent, which in the EU is a problem. We recommend the switch. Server-side counts from your host or your own analytics behind consent give you the same numbers without the question.

Step 4: publish, scan, prove it

The preview URL gets the preview key, the published app and the custom domain get the production key. The scan and the install check always run against the live URLs.

File each finding under its category, set the links to your privacy policy and, if you are in Germany, your imprint, and publish the banner. Then run the install check. It loads your published URL like a visitor and confirms that the runtime ran first and nothing non-essential fired before a choice. That tick, with its timestamp, is the artefact you keep. Take a screenshot of the Reject click in a private window as well; the browser’s storage panel should show no analytics or marketing cookies afterwards.

When you connect a custom domain later, update the domain in the site settings so the scanner follows it. The key does not change, so the tag in index.html stays as it is.

If you use Google Analytics or Google Ads with visitors in the EEA, UK or Switzerland, Google requires Consent Mode v2 signals. The runtime pushes the denied defaults before any Google tag can run, and updates them when the visitor decides, so there is nothing to code. Two details matter in a Lovable app specifically. GA4 needs a page view on every client-side route change, which the usual useEffect on the router location handles; since the gtag script itself is held until analytics is granted, those calls queue harmlessly until then. And keep the GA4 snippet in index.html, not in a component, so the text/plain gate applies to it. The full signal list and the June 2026 change are in the Consent Mode post.

What happens when you prompt again

Prompts rewrite src/. They rarely touch index.html, but “rebuild the landing page from scratch” or “add the TikTok pixel” can, and an agent that adds a tag adds it live, not gated. Two safety nets cover that. The scheduled re-scan loads the published app again with consent denied and raises an alert on anything new before consent, with the date it appeared. And if GitHub sync is on, the diff of every prompt lands in your repository, where the CLI check can block a deploy that introduces an unclassified tracker. Treat the alert like a failing test: sort the new vendor, publish, done.

Checklist

  • The consent tag is the first element inside head in index.html, with the production key.
  • Every analytics and marketing script in index.html has type="text/plain" and a category.
  • Lovable visitor analytics is either off or explained in the declaration, after a scan told you what it does.
  • The first scan ran against the published URL, every finding has a category, and the banner is published.
  • The install check passed, and Reject in a private window leaves no analytics or marketing cookies.
  • Scheduled re-scans are on, so the next prompt cannot quietly add a pixel.

If you want the shorter version with the free-plan details, the Lovable integration guide has it, and the free scan tells you what your app loads today without an account.

Sources

  1. Lovable documentation, “Project analytics”, read 5 September 2026
  2. Lovable FAQ, “Can I see analytics for my published projects?”, read 5 September 2026
  3. Lovable documentation, “View and edit your project’s code”, read 5 September 2026
  4. Lovable documentation, GitHub integration and Git sync overview
  5. Google, “Consent mode on websites and mobile apps”, Tag Platform documentation
  6. CNIL, “Cookies placed without consent: SHEIN fined 150 million euros”, 3 September 2025
  7. EDPB, Guidelines 03/2022 on deceptive design patterns, adopted 14 March 2022

next step

See what your site loads before consent

The free scan reads your homepage and lists the trackers. No account, nothing stored.