Platforms

How to add a cookie consent banner to a Bubble app

In Bubble, open the Settings tab of the editor, then SEO / metatags, and paste the snippet in the Script/meta tags in header field so it is on every page; each page's own header field exists for single pages. Mark your analytics and marketing scripts in the same field and add the Cookie preferences link with an HTML element.
Published 20 October 2026 · By the Cookiequiet team · Markdown

Steps

Open the SEO / metatags settingsIn the Bubble editor, open the Settings tab and click SEO / metatags.
Paste the snippet in the header fieldPaste the Cookiequiet snippet at the top of the Script/meta tags in header field. Bubble documents that only script, meta and link tags are valid there, and this field applies to every page of the app.
Mark the tags you addAdd your Google tag or Meta Pixel below the snippet in the same field, each script tag marked with type="text/plain" and data-cq-category, or with Google's default consent block above the Google tag for Consent Mode.
Handle embeds and pluginsIn HTML elements, write iframes with data-cq-src instead of src. Plugins that load analytics or pixels with JavaScript are held by the auto-blocker when they are known trackers; check them in the test step.
Add the Cookie preferences linkPlace an HTML element in your footer (or footer reusable element) containing a link with href="#cq-preferences" and data-cq-show-preferences.
Deploy and testTest on the development version first, then deploy to live. In a private window, click Reject all and check that no _ga or _fbp cookie is set. Accept all, reload, and check the consent log.

Where to paste the snippet in Bubble

Bubble has one place for code that must be on every page of an app. In the editor, open the Settings tab, then SEO / metatags, and paste the snippet at the top of the Script/meta tags in header field:

html
<script src="https://cookiequiet.com/cq.js" data-site="YOUR_SITE_KEY" data-consent-mode="1" data-auto-block="1" defer></script>

Bubble's manual notes that only <script>, <meta> and <link> tags are valid in that field; anything else may be moved into the body by the browser. The field applies to every page, in the development version and in the live version. Each page also has its own header field in the page settings (open the page element's property editor), which applies to that page only: use it for a tag that one page needs, never for the banner itself. If the tag does not appear in the page source after you deploy, check that your plan includes custom header scripts.

How to handle the tags your app loads

Tags you paste. Below the snippet, in the same field. Two ways:

  • marked, so nothing loads before consent:
html
<script type="text/plain" data-cq-category="analytics" src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXX"></script>
<script type="text/plain" data-cq-category="analytics">
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-XXXXXXX');
</script>
  • or in Consent Mode, with Google's default consent block above the Google tag, as described in the Google Analytics 4 guide. The Meta Pixel is marked marketing; see the Meta Pixel guide for its noscript caveat.

Plugins. Bubble plugins that add Google Analytics, the Meta Pixel, Hotjar or a chat widget insert their script with JavaScript at run time. With data-auto-block="1", Cookiequiet holds the scripts and iframes of about 80 known trackers created this way until their category is granted; a plugin that uses an unknown host runs, which the test and the cookie scanner reveal. Where the plugin offers a manual "initialize" action, trigger it from a workflow only after consent (see below).

HTML elements. Bubble's HTML element prints its content in the page, so marked scripts and data-cq-src iframes work inside it. Remember that a page-level HTML element only exists on that page, and that Cookiequiet activates marked scripts when a choice is applied on load and after each choice: content shown later (a popup, a group made visible by a workflow) should rely on data-cq-src or on the API rather than on marked scripts.

Workflows and the API. A "Run JavaScript" action (from a JavaScript plugin such as Toolbox) can call window.Cookiequiet.get() to read the stored choice (its c array lists the granted categories) and window.Cookiequiet.showPreferences() to open the preferences centre from any button.

Add an HTML element to the footer, or to the footer reusable element so it appears on every page, with:

html
<a href="#cq-preferences" data-cq-show-preferences>Cookie preferences</a>

A button wired to a Run JavaScript action calling window.Cookiequiet.showPreferences() works too, and the floating preferences button in the banner settings is the no-code fallback.

How to test

  1. Open the development version (the version-test URL) in a private window and click Reject all.
  2. Check the cookies in the developer tools: cq_consent, Bubble's own session cookies, nothing from Google or Meta.
  3. Clear the cookies, click Accept all, reload: the marked tags run.
  4. Deploy to live and repeat once on the live URL.
  5. Check the consent log in the Cookiequiet dashboard.

What is specific to Bubble

  • Development and live share the header field; the consent log records the page path, so test entries are easy to spot.
  • Bubble's own cookies keep the session and the app running and are necessary.
  • Native wrappers and iframes. An app embedded in another site's iframe shows the banner inside the iframe; the choice is stored for the app's domain.
  • Page-level header fields are printed after the global field, so a tag added for one page still sees the snippet first.

Questions

Yes. The Script/meta tags in header field is part of the app's settings and applies to both versions; test on version-test, then deploy to live.
The field under Settings, then SEO / metatags applies to every page; the field in a page's settings applies to that page only. The banner goes in the global field; a tag that one page needs can go in that page's field, below the snippet in the rendered head.
If the plugin inserts the Google tag with JavaScript, the auto-blocker holds it until analytics is granted, because gtag.js is a known tracker. Check it in a private window; if the plugin offers a manual initialization action, run it from a workflow after consent instead.
Yes. A Run JavaScript action (from a JavaScript plugin such as Toolbox) calling window.Cookiequiet.showPreferences() opens the preferences centre, and window.Cookiequiet.get() returns the stored choice.

Put a quiet banner on your website today

Free for one website with every core feature, no card and no trial clock. Upgrade a website to Starter for $3 a month to match your brand with AI and drop the branding, or to Pro for $9 to design it with the AI agent.