Framer
Overview
Framer's Cookie Banner component provides a native consent management solution that:
- Stores user consent preferences in
localStorageunder the keyframerCookiesConsentMode - Integrates with Google Tag Manager via Consent Mode v2
- Supports different consent levels: Necessary, Preferences, Analytics, and Marketing
Dreamdata Analytics can be configured to respect these consent preferences, always initializing but running cookieless accordingly based on user consent.
Prerequisites
Before you begin, ensure you have:
- A Framer website with the Cookie Banner component added
- A Google Tag Manager account (required)
- Access to your Dreamdata account and API key
- Administrative access to your Framer project settings
- (Optional) Access to Framer's custom code settings for SPA tracking placement
Please note that this guide provides a basic template of how to set up. However, it is not a one-size-fits-all for all Framer sites. For unique problems on your site it is important to have a developer available to troubleshoot and customize this template to your needs.
Part 1: Framer Cookie Banner Setup
Adding the Cookie Banner Component
- In Framer, open the Insert Menu
- Search for "Cookie Banner" and drag it onto your canvas
- Add the component to every page, or preferably to a common component like a navbar or footer
Configuring Consent Options
The Cookie Banner supports different consent configurations:
| Consent Type | Google Consent Mode Mapping |
|---|---|
| Necessary | security_storage + functionality_storage |
| Preferences | personalization_storage |
| Analytics | analytics_storage |
| Marketing | ad_storage + ad_user_data + ad_personalization |
For Dreamdata Analytics, ensure the Analytics option is available for users to consent to.
Regional Settings
Configure the banner behavior for different regions:
- EU visitors: Use "Customizable" or "Accept/Reject" to comply with GDPR
- Rest of world: Can use "No Choice" for automatic acceptance, or match EU settings
Part 2: Google Tag Manager Setup
Google Tag Manager (GTM) is required for integrating Dreamdata Analytics with Framer. GTM handles the main Dreamdata initialization and consent management integration.
Create a GTM Container
- Go to Google Tag Manager
- Create a new container for your website (or use an existing one)
- Note your Container ID (format:
GTM-XXXXXXX)
Enable Consent Mode
- In GTM, navigate to Admin → Container Settings
- Enable Consent Overview
- This allows tags to respect user consent preferences
Connect GTM to Framer
- In Framer, select your Cookie Banner component
- In the properties panel, find the GTM Container ID field
- Enter your Container ID (e.g.,
GTM-XXXXXXX)
Part 3: Dreamdata Tag Configuration
Create a Custom HTML Tag
- In Google Tag Manager, click Tags → New
- Name the tag "Dreamdata Analytics"
- Select Custom HTML as the tag type
Add the Dreamdata Script
Paste the consent-aware initialization script from the setup in your Dreamdata app into the Custom HTML field.
Navigate to Dreamdata and Data Platform > Sources > JavaScript v2.0. Click "Reconfigure script" to go through a wizard on how to set up the script.
Configure Tag Triggering
- Click Triggering
- Select All Pages trigger
- Save the tag
Part 4: SPA Page and Event Tracking
Framer websites are Single Page Applications (SPAs), which means traditional page load events don't fire during navigation. The SPA tracking script listens for Framer's custom events to capture page views, link clicks, and form submissions.
Setting Up Tracking IDs in Framer (Optional)
Tracking IDs are only required if you want to track clicks and submissions from Framer's native links and forms. If you use external form providers (such as HubSpot, Typeform, or Marketo), those are tracked separately through Dreamdata's automatic form tracking and do not require Framer tracking IDs.
To configure tracking IDs for Framer native components:
- For links: When adding a link in Framer, include a unique tracking ID in the link settings
- For forms: When selecting a form on the canvas, add a tracking ID in the properties panel
For detailed instructions, see How to track links and forms in Framer.
Create a Page and Event Tracking Tag
- In GTM, create another Custom HTML tag
- Name it "Dreamdata Framer Tracking"
- Add the following script:
<script>
(function () {
/**
* Gets the appropriate Dreamdata analytics instance.
* Returns the full tracking instance if initialized with consent,
* otherwise falls back to the cookieless instance.
*/
function getAnalytics() {
if (window.dreamdata && window.dreamdata.initialized) {
return window.dreamdata;
}
return window["dreamdata-cl"] || null;
}
// Track the last URL to detect navigation changes
var lastUrl = window.location.href;
/**
* Fires a page view event with full context.
* @param {string} referrer - The previous URL (internal referrer)
*/
function firePage(referrer) {
var analytics = getAnalytics();
if (!analytics || typeof analytics.page !== "function") {
return;
}
var loc = window.location;
analytics.page({
path: loc.pathname,
url: loc.href,
title: document.title,
search: loc.search,
referrer: referrer,
});
}
/**
* Handles Framer's pageview event by checking for URL changes.
* Fires a page view only when the URL has actually changed.
*/
function handlePageView() {
var currentUrl = window.location.href;
if (currentUrl !== lastUrl) {
var referrer = lastUrl;
lastUrl = currentUrl;
firePage(referrer);
}
}
/**
* Handles Framer's click event for tracked links.
* @param {CustomEvent} event - Framer click event with detail object
*/
function handleClick(event) {
var analytics = getAnalytics();
if (!analytics || typeof analytics.track !== "function") {
return;
}
// Safely access event detail properties
var detail = event.detail || {};
analytics.track("Link Clicked", {
trackingId: detail.trackingId || "",
href: detail.href || "",
});
}
// Register event listeners for Framer's custom events
document.addEventListener("framer:pageview", handlePageView);
document.addEventListener("framer:click", handleClick);
})();
</script>
This script:
getAnalytics(): Returns the appropriate Dreamdata instance (full or cookieless) based on consent statehandlePageView(): Listens for Framer'sframer:pageviewevent and fires page views when the URL changeshandleClick(): Tracks link clicks with the configured tracking ID fromframer:clickevents
SPA Tracking Script Warning
If you place the SPA tracking script, you are responsible for maintaining it. The script depends on Framer's internal events (framer:pageview,
framer:click, framer:formsubmit) and may break if
Framer updates their platform. See
How to track page views, links and forms in Framer.Configure Triggering
- Set the trigger to All Pages
- Save and publish the tag
Alternative: Place SPA Script in Framer Custom Code
If you prefer, you can move the SPA page tracking script from GTM to Framer's custom code instead:
- Remove the SPA script from GTM (keep only the main Dreamdata tag in GTM)
- Access Framer Custom Code Settings
- In your Framer project, click the Settings icon
- Navigate to Site Settings → Custom Code
- Add the SPA script to "End of
<head>tag"- This is Framer’s recommended location for global scripts that do not depend on the DOM being loaded. The SPA script only hooks into navigation/pageview events and requires the Dreamdata analytics object (from the main Dreamdata tracking code, typically loaded via GTM) to be initialized first.
- If you customize the SPA script to access or manipulate DOM elements on
load, place that customized script at the end of the
<body>instead. - Paste the same SPA tracking script shown above
- Leave the Run once option enabled to ensure the SPA tracking script only registers its event listeners once and to prevent duplicate pageview tracking.
Optional Part 5: Form Tracking
In most cases basic Framer forms will be automatically tracked by the form tracking for html forms. This set up is needed in cases where your form submits are not being picked up by the script automatically. You can check for form tracking events in the Network tab by filtering by dreamdata, or by using the tracking validator..
Adding Custom Code
To track forms in Framer the follow section can be added as Custom Code. Set this to trigger on All pages and On Every Page Visit and be place at the end of the body section.
The following code can be copy and pasted into the custom code field. Note that if your email field has a different name you'll need to edit the code to handle it:
<script>
document.addEventListener("framer:formsubmit", (event) => {
const trackingId = event.detail.trackingId;
const emailInput = document.querySelector(
'input[name="Email"], input[name="email"]',
);
const emailValue = emailInput
? emailInput.value.trim().toLowerCase()
: null;
if (emailValue) {
dreamdata.identify(null, {
email: emailValue,
});
}
dreamdata.track("Form submitted: " + trackingId);
});
</script>
To add a name for a form add it in the Tracking field in the Form section of the Framer editor. The naming convention in the custom code allows you to see different names for each form if you have multiple on your site. If you only have one you can simply add the name in the custom code snippet and remove the reference to the trackingId.
Removing Automatic Form Tracking
In the dreamdata script find the formTracking object and remove the statement "html=true". This is needed to prevent duplicate form tracks in case of inconsistent firing of the automatic tracking.
Consent Updates
The Dreamdata script automatically handles consent updates. When a user changes their consent preferences via the Framer Cookie Banner, the script:
- Always initializes and tracks in cookieless mode by default
- Monitors the GTM dataLayer for consent changes (
analytics_storagegranted/denied) - Switches to full tracking with cookies when analytics consent is granted
- Reverts to cookieless mode when consent is revoked (tracking continues without cookies)
No additional GTM triggers or configuration is required for consent handling.
Testing and Debugging
Enable Debug Mode
To see detailed console logs during testing, open your browser's developer console and run:
localStorage.setItem("DD_DEBUGGER", "true");
Then refresh the page. You'll see logs for:
- Consent state changes
- DataLayer updates
- Dreamdata initialization steps
Verify Consent Flow
- Clear cookies and localStorage to simulate a new visitor
- Load your Framer site - the Cookie Banner should appear
- Check the console - Dreamdata should initialize in cookieless mode
- Accept analytics cookies - Dreamdata should switch to full tracking mode
- Navigate between pages - Verify page views are tracked
Check in Dreamdata
- Log in to your Dreamdata account
- Navigate to the debugger or live events view
- Verify page views are being received from your Framer site
Troubleshooting
Events Not Appearing in Dreamdata
Symptoms: Page views or track events are not showing in the Dreamdata debugger.
Solutions:
- Verify GTM is loading: Open browser DevTools → Network tab → search for
gtm.js. If not found, check your GTM Container ID in Framer. - Check for script errors: Open browser DevTools → Console tab → look for JavaScript errors related to Dreamdata or GTM.
- Confirm the tag is firing: In GTM Preview mode, verify the "Dreamdata Analytics" tag shows as "Fired".
- Check your API key: Ensure the writeKey in your Dreamdata script matches the one in your Dreamdata account under Data Platform > Sources > JavaScript v2.0.
Consent Not Being Detected
Symptoms: Dreamdata stays in cookieless mode even after accepting cookies.
Solutions:
- Check localStorage: In browser DevTools → Application → Local Storage →
look for
framerCookiesConsentMode. Verify it contains"analytics": true. - Verify GTM Consent Mode: In GTM Preview, check that
analytics_storageshows as "granted" after accepting cookies. - Check Cookie Banner setup: Ensure your Framer Cookie Banner component has the correct GTM Container ID configured.
SPA Navigation Not Tracking
Symptoms: Only the first page view is tracked; navigation between pages is not recorded.
Solutions:
- Verify the SPA tracking tag: Ensure the "Dreamdata Framer Tracking" tag exists in GTM and is set to fire on "All Pages".
- Check event listeners: In browser DevTools → Console, run
document.dispatchEvent(new CustomEvent("framer:pageview")). If working correctly, you should see a page event in the Network tab. - Confirm Framer events: For native Framer links and forms that should fire Framer events, ensure tracking IDs are configured. External form providers (for example, Typeform or HubSpot forms) do not use Framer tracking IDs.
GTM Container Not Loading
Symptoms: GTM scripts are not loading on your Framer site.
Solutions:
- Check Container ID format: Ensure the ID follows the format
GTM-XXXXXXX(with theGTM-prefix). - Verify Cookie Banner placement: The Cookie Banner component with your GTM ID must be present on every page (use a shared navbar or footer component).
- Check for ad blockers: Some ad blockers prevent GTM from loading. Temporarily disable them for testing.
Duplicate Events
Symptoms: Events appear multiple times in Dreamdata.
Solutions:
- Check for duplicate tags: Ensure you only have one Dreamdata Analytics tag in GTM.
- Verify single script placement: If using Framer Custom Code for the SPA script, ensure it's not also in GTM.
- Check Cookie Banner placement: The Cookie Banner should only be on one shared component, not duplicated on multiple pages.
Summary
With this GTM-based integration, Dreamdata Analytics will:
- ✅ Always initialize and track in cookieless mode by default
- ✅ Respect consent changes in real-time
- ✅ Track page views correctly on Framer SPA navigation
- ✅ Switch between cookieless and full tracking based on consent
- ✅ Comply with GDPR and other privacy regulations
For more information about Framer's Cookie Banner, see the official Framer documentation.
Related Documentation
- Tracking Websites - General guide for installing the Dreamdata JavaScript script
- Tracking SPAs - Detailed guide for Single Page Application tracking with framework-specific examples
- Cookieless Account Analytics - Learn more about how cookieless tracking works and its impact on data collection
- Form Tracking - Additional options for tracking form submissions beyond Framer's built-in events