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.Steps
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.
How to add the Cookie preferences link
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
- Open the development version (the
version-testURL) in a private window and click Reject all. - Check the cookies in the developer tools:
cq_consent, Bubble's own session cookies, nothing from Google or Meta. - Clear the cookies, click Accept all, reload: the marked tags run.
- Deploy to live and repeat once on the live URL.
- 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.