Loading tutorials…
Loading tutorials…
GTM is the right move once you are running 2+ marketing pixels. The wrinkle on Webflow: GTM needs both a Head snippet AND a body-open snippet — and Webflow only gives you one body-end slot. Here is the workaround that ships clean.
Who this is forWebflow site owners adding their second or third marketing pixel (GA4 + Meta Pixel + LinkedIn Insight, etc.). If you are still on a single GA4 install, you do not need GTM yet — wait until the second tag, then switch. Adding GTM later is harder than starting with it.
What you'll need
Step 1
tagmanager.google.com → Create Account → Container name = your domain → Target platform = Web. GTM gives you two snippets: <head> and <body>.
Open tagmanager.google.com. Sign in with the Google account you want as Admin.
Click Create Account. Account name = your business. Country = your country. Container name = your custom domain (without https). Target platform = Web. Accept terms.
GTM lands you on the container overview and pops up the install instructions. Two snippets: one for <head> and one for immediately after <body>.
Copy both. The Head snippet is a <script> wrapper. The Body snippet is a <noscript> wrapper. Both contain your container ID (GTM-XXXXXXX).
Keep this tab open — you will be back here to publish the container after configuring tags.
Step 2
Webflow doesn't have a body-open slot. The accepted workaround: paste both snippets in Head Code, one after the other. Works in 100% of cases we have tested.
Open Webflow Designer → top-left logo → Project Settings → Custom Code.
Paste the GTM Head snippet at the very top of Head Code. This is critical — GTM should load before any other tag.
Paste the GTM Body snippet (the <noscript> one) immediately below the Head snippet. Yes, this puts it in <head> rather than after <body> as Google's docs say. Webflow does not have a true body-open slot, and the <noscript> tag is benign in <head>. It works.
Don't try to put the Body snippet in Footer Code (which is end-of-body, not start-of-body). The <noscript> tag works at the start of body OR end — but Head is the safer choice on Webflow.
Save Changes, then Publish to your custom domain.
Step 3
Chrome extension "Tag Assistant Legacy" + GTM Preview mode. Reload your site, check that GTM container loads.
In GTM, top-right click Preview. A new tab opens (tagassistant.google.com). Enter your live URL. Click Connect.
A new tab opens with your site, with a small connected badge at the bottom. The Tag Assistant tab shows real-time event firing.
In Tag Assistant, you should see Container Loaded → Initialization → Window Loaded events. No tags yet — we have not added any.
If Tag Assistant says 'Did not detect Google Tag Manager': the snippet did not publish. Check Webflow Designer → Publish → confirm the project was published to the custom domain after pasting Custom Code.
Alternative verification: View Page Source on your live URL, search for "GTM-" — your container ID should appear inside a <script> tag in the head.
Step 4
GTM → Tags → New → Google Analytics: GA4 Configuration → Measurement ID → All Pages trigger. Then delete the direct GA4 snippet from Webflow.
In GTM → Tags → New. Tag name: 'GA4 - Configuration.' Tag Configuration → Google Analytics → Google Tag → enter your G-XXXXXXXXXX Measurement ID.
Trigger → All Pages → Initialization. Save.
Click Submit (top-right) → Publish → Version name = 'GA4 base config'. Publish.
Open your live site in incognito. In GTM → Preview mode, refresh the page. You should see the 'GA4 - Configuration' tag fire. In GA4 → Realtime, you should see yourself as 1 user.
Now remove the direct GA4 install from Webflow Project Settings → Custom Code → Head Code. Save Changes → Publish.
Re-verify GA4 → Realtime — should still show 1 user. If both sites are still showing users equally after 24 hours, the old snippet is still cached somewhere. Hard-refresh and re-check. CRITICAL: never leave both the direct snippet AND the GTM-fired tag — every page would double-count for as long as both run.
Step 5
Webflow forms don't natively push to dataLayer. Add a small site-wide script that listens for form-success and pushes 'form_submit' with form name and page path.
Webflow Forms don't expose a dataLayer event by default. You add one via Footer Code (end-of-body).
Webflow Designer → Project Settings → Custom Code → Footer Code. Paste:
<script>document.addEventListener('DOMContentLoaded', function() { document.querySelectorAll('form').forEach(function(form) { form.addEventListener('submit', function(e) { window.dataLayer = window.dataLayer || []; window.dataLayer.push({ event: 'form_submit', form_name: form.getAttribute('data-name') || form.id, page_path: window.location.pathname }); }); }); });</script>
This script listens to every form submit on the site. It pushes 'form_submit' to the dataLayer with the form's data-name (Webflow auto-sets this) and the current page path.
In GTM → Triggers → New → Custom Event → Event name = 'form_submit.' Save trigger.
Create a new GA4 Event Tag in GTM: Event name = 'form_submit', parameters = { form_name: {{DLV - form_name}}, page_path: {{DLV - page_path}} } where DLV variables are Data Layer Variables you create in GTM → Variables.
Submit + Publish GTM. Test in GTM Preview mode by submitting a form on your live site. The 'form_submit' event should fire and forward to GA4 → DebugView.
Step 6
Now that GTM is the orchestration layer, every new pixel goes through it. Use the Community Template Gallery for Meta Pixel — much easier than custom HTML.
GTM → Tags → New → Tag Configuration → search "Facebook Pixel" or "Meta Pixel" in the Community Template Gallery.
Add the 'Facebook Pixel' template (by Simo Ahava is the most-vetted). Enter your Pixel ID. Trigger: All Pages.
Submit + Publish. Verify with Meta Pixel Helper on the live site — should show PageView firing once, from GTM.
Now remove any direct Pixel install from Webflow Custom Code. Same rule as GA4 — both running = double-count.
For LinkedIn Insight Tag, TikTok Pixel, Hotjar, etc.: each gets its own Tag in GTM. The Community Template Gallery has vetted templates for nearly every major pixel.
Step 7
GTM → Admin → Environments → create Production and Staging. GTM versions every publish — leverage this for safe rollbacks.
GTM → Admin → Environments. Create two: Production (already exists as Live) and Staging.
Staging environment is useful when testing new tags before pushing live. The Staging environment generates its own URL and code snippet — paste in a separate Webflow staging project if you have one.
Every Submit + Publish in GTM creates a Version. GTM → Versions shows all published versions. To roll back: click an older Version → Publish to Live → tags revert.
Use clear Version names: 'Add GA4 + Meta Pixel via GTM,' not 'Updated.' Future-you (or the next person) will thank current-you.
GTM does NOT have a Slack-style audit log of who changed what at the tag level — only versions. If you have multiple users, version names are your audit trail.
Common mistakes
Running GTM AND direct GA4/Pixel scripts at the same time
What goes wrong: Every tag double-fires. GA4 sessions double. Pixel events double. Reported CPA halves overnight, you scale ad spend, then 4-6 weeks later real attribution surfaces and you realize half the budget was based on phantom data.
How to avoid: When you add a tag to GTM, IMMEDIATELY remove the direct version from Webflow Custom Code. Verify with Meta Pixel Helper / GA4 DebugView that each event fires exactly once.
Putting GTM in Page Settings → Custom Code instead of Project Settings
What goes wrong: GTM only fires on the one page you edited. Every other page on the site has no analytics. You think GTM is broken; really it just is not installed site-wide.
How to avoid: Project Settings → Custom Code → Head Code. Site-wide install. Never use page-level Custom Code for GTM (or any tag manager).
Forgetting to Publish in GTM
What goes wrong: Adding a tag in GTM and clicking Save does NOT push it live. You need to click Submit + Publish. Tags configured but unpublished feel like they should fire but never do — you debug for hours.
How to avoid: After every tag change in GTM, click Submit (top-right) → enter version name → Publish. Verify in Preview mode AND on the live site with Tag Assistant.
Not pushing form-submit events to dataLayer
What goes wrong: Webflow form submissions don't trigger any dataLayer event by default. You think GTM tracks your leads, but it does not. Every lead conversion you report to Meta or GA4 is missing.
How to avoid: Add the site-wide form-submit listener (Footer Code) shown in step 5. Verify in GTM Preview that the form_submit event appears in the event list after you submit a form.
Using auto-generated form names like "Form 1" and "Form 2"
What goes wrong: Every form on the site reports as 'Form 1' or 'Form 2' in GA4. You cannot tell which form drove which conversion. Funnel analysis becomes guesswork.
How to avoid: In Webflow Designer, click each form → Settings panel → Form Settings → Name → set a descriptive name (e.g., 'Contact Form,' 'Newsletter Footer,' 'Demo Request'). This populates data-name and shows up in dataLayer pushes.
Not using the Community Template Gallery for Pixel installs
What goes wrong: You hand-write a Custom HTML tag for Meta Pixel with code from a 2019 blog post. The code missing fbq('init', ...) parameter changes from Meta's recent updates, and the Pixel does not pass Advanced Matching data to Meta. Match rates suffer.
How to avoid: GTM → Tags → New → Community Template Gallery. Use the vetted Simo Ahava Meta Pixel template (or equivalent for other tools). These are maintained against vendor API changes.
Recap
Done — what's next
How to install Google Analytics 4 on a Webflow site
Read the next tutorial
Hand it off
A clean GTM install on Webflow with GA4 + Meta Pixel + LinkedIn Insight + form tracking is a 4-6 hour project for someone who knows the Webflow-specific quirks (body snippet location, form dataLayer push, environment setup). A vetted specialist on EverestX wires it up in one afternoon — typically $80-160 at $14-16/hr.
See specialist rates
If GA4 is your only tag, paste directly. If you have GA4 + 1 more pixel (Meta, LinkedIn, TikTok, Hotjar), switch to GTM now. The migration is easier when the stack is small. GTM saves hours of Webflow Custom Code edits every time you add or change a tag.
The accepted workaround on Webflow is to paste both the head snippet AND the body snippet in Project Settings → Custom Code → Head Code, one after the other. Yes, this puts the <noscript> in <head> rather than after <body>. Webflow ships it fine and Google does not penalize. We have audited 50+ Webflow sites running this pattern with no issues.
No. Custom Code is a paid feature — requires a Site plan ($14/mo Basic minimum). Workspace plans alone do not include Custom Code on hosted sites.
GTM has built-in Click triggers. GTM → Triggers → New → Just Links (for outbound links) or All Elements (for any clickable element). Use CSS selectors that match the button you want to track. Or, in Webflow, add a custom attribute like data-track='cta-hero' to specific elements and target that attribute in GTM.
Webflow does not have a native consent banner. Most Webflow sites use Cookiebot, Termly, or Iubenda — all integrate with GTM via Consent Mode v2. Add the consent-mode wrapper in GTM (Tags → Consent Settings) and configure each tag's consent requirements. This is required for EU traffic.
Historical data is unaffected — GA4 and Meta keep all past data regardless of where the snippet now lives. The migration is purely about future tag firing. As long as you avoid the double-fire window (both direct and GTM running for more than 24 hours), reporting is continuous.
Webflow
Webflow doesn't have a native GA4 field anymore — every install goes through Custom Code. Most DIY setups end up double-counting from the webflow.io staging subdomain or missing events from form submits. This walks the install + the filters that fix both.
Webflow
Webflow has no server-side hook, which means the Meta Pixel alone misses 20-40% of conversions on iOS. This walks through the Pixel install AND the three legitimate Conversions API workarounds for Webflow — Zapier, Stape, or HubSpot-as-middleware.
Webflow
Webflow Forms work great until you realize submissions are going nowhere — notification email mis-configured, no CRM sync, no tracking event fired. This walks the full setup: form, redirect, tracking, and CRM integration.
Webflow
DIY Webflow is great for the first 6 months — the visual editor really is that good. After that, the math usually flips. This is the honest framework: when self-managing costs more than hiring help.