Webflow Google Analytics Integration
Complete guide to setting up Google Analytics 4 (GA4) on your Webflow site for comprehensive user behavior and conversion tracking.
Overview
Webflow provides flexible options for Google Analytics 4 integration through custom code embeds and site settings. As a visual web design platform with powerful CMS capabilities, Webflow allows you to implement sophisticated GA4 tracking without needing to write extensive code. Whether you're building a portfolio, business site, or ecommerce store, GA4 integration provides essential analytics for understanding visitor behavior.
Key Benefits
- Custom Code Embeds: Add GA4 tracking through Webflow's code embed features
- Site-Wide Tracking: Apply tracking code across all pages automatically
- Ecommerce Ready: Track Webflow Ecommerce transactions and product interactions
- CMS Integration: Track dynamic CMS content and collections
- Form Tracking: Monitor form submissions and conversions
Plan Requirements
- Custom Code: Available on all paid Webflow plans
- Ecommerce Tracking: Requires Ecommerce plan
- Site Settings Access: Available to site owners and editors
Installation Methods
Method 1: Site-Wide Custom Code (Recommended)
Add GA4 tracking to all pages using Webflow's site settings.
Step 1: Access Site Settings
- Open your Webflow project
- Click the Settings icon (gear) in the left panel
- Navigate to Custom Code tab
Step 2: Add GA4 Tracking Code
- In the Head Code section, paste:
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-XXXXXXXXXX', {
'send_page_view': true,
'cookie_flags': 'SameSite=None;Secure'
});
</script>
- Replace
G-XXXXXXXXXXwith your Measurement ID - Click Save Changes
- Publish your site
Step 3: Verify Installation
- Visit your published site
- Open browser DevTools (F12)
- Check for gtag.js script in Network tab
- Verify page view in GA4 Real-time reports
Method 2: Page-Specific Custom Code
For page-specific tracking or testing.
Add Code to Individual Pages
- Select a page in the Pages panel
- Click the Settings icon next to the page name
- Go to Custom Code in page settings
- Add GA4 code in Before
</body>tag or Inside<head>tag - Publish changes
Method 3: Embed Element
For inline tracking code within page content.
- Drag an Embed element onto your page
- Paste GA4 tracking code
- Position as needed
- Publish site
Ecommerce Tracking Configuration
Webflow Ecommerce Integration
Track Webflow Ecommerce events for comprehensive store analytics.
Product Page Tracking
Add custom code to product template:
<script>
// Track product views
gtag('event', 'view_item', {
'currency': 'USD',
'value': parseFloat('{{wf {"path":"default-price","type":"PlainText"\} }}'),
'items': [{
'item_id': '{{wf {"path":"slug","type":"PlainText"\} }}',
'item_name': '{{wf {"path":"name","type":"PlainText"\} }}',
'item_category': '{{wf {"path":"category","type":"PlainText"\} }}',
'price': parseFloat('{{wf {"path":"default-price","type":"PlainText"\} }}')
}]
});
</script>
Add to Cart Tracking
Track add-to-cart button clicks:
<script>
document.addEventListener('DOMContentLoaded', function() {
// Select add to cart buttons
const addToCartButtons = document.querySelectorAll('.w-commerce-commerceaddtocartbutton');
addToCartButtons.forEach(function(button) {
button.addEventListener('click', function() {
// Get product data from page
const productName = document.querySelector('.w-commerce-commerceproducttitle').textContent;
const productPrice = parseFloat(document.querySelector('.w-commerce-commerceproductprice').textContent.replace(/[^0-9.-]+/g,""));
gtag('event', 'add_to_cart', {
'currency': 'USD',
'value': productPrice,
'items': [{
'item_name': productName,
'price': productPrice,
'quantity': 1
}]
});
});
});
});
</script>
Checkout Tracking
Add to checkout page:
<script>
// Track begin checkout
gtag('event', 'begin_checkout', {
'currency': 'USD',
'value': parseFloat(document.querySelector('.w-commerce-commercecheckoutorderinfosummaryprice').textContent.replace(/[^0-9.-]+/g,"")),
'items': getCartItems()
});
function getCartItems() {
const items = [];
document.querySelectorAll('.w-commerce-commercecheckoutorderitem').forEach(function(item) {
items.push({
'item_name': item.querySelector('.w-commerce-commerceorderitemproductname').textContent,
'price': parseFloat(item.querySelector('.w-commerce-commercecheckoutordersummaryprice').textContent.replace(/[^0-9.-]+/g,"")),
'quantity': parseInt(item.querySelector('.w-commerce-commercecheckoutorderitemquantity').textContent)
});
});
return items;
}
</script>
Purchase Tracking
Add to order confirmation page:
<script>
// Track purchase on order confirmation
gtag('event', 'purchase', {
'transaction_id': '{{wf {"path":"order-id","type":"PlainText"\} }}',
'value': parseFloat('{{wf {"path":"order-total","type":"PlainText"\} }}'.replace(/[^0-9.-]+/g,"")),
'currency': 'USD',
'tax': parseFloat('{{wf {"path":"tax-total","type":"PlainText"\} }}'.replace(/[^0-9.-]+/g,"")),
'shipping': parseFloat('{{wf {"path":"shipping-total","type":"PlainText"\} }}'.replace(/[^0-9.-]+/g,""))
});
</script>
Advanced Event Tracking
Form Submission Tracking
Track Webflow form submissions:
<script>
document.addEventListener('DOMContentLoaded', function() {
// Track form submissions
const forms = document.querySelectorAll('form');
forms.forEach(function(form) {
form.addEventListener('submit', function(e) {
const formName = form.getAttribute('name') || 'Form';
gtag('event', 'form_submit', {
'form_name': formName,
'page_path': window.location.pathname
});
});
});
});
</script>
CMS Collection Tracking
Track interactions with CMS content:
<script>
// Track CMS collection item views
gtag('event', 'view_item', {
'content_type': 'blog_post',
'item_id': '{{wf {"path":"slug","type":"PlainText"\} }}',
'item_name': '{{wf {"path":"name","type":"PlainText"\} }}',
'item_category': '{{wf {"path":"category","type":"PlainText"\} }}'
});
</script>
Button Click Tracking
Track CTA button interactions:
<script>
document.querySelectorAll('.cta-button').forEach(function(button) {
button.addEventListener('click', function() {
gtag('event', 'cta_click', {
'button_text': this.textContent.trim(),
'button_url': this.getAttribute('href'),
'page_location': window.location.href
});
});
});
</script>
Scroll Depth Tracking
Monitor content engagement:
<script>
let scrollDepths = {25: false, 50: false, 75: false, 100: false};
window.addEventListener('scroll', function() {
const scrollPercent = (window.scrollY / (document.documentElement.scrollHeight - window.innerHeight)) * 100;
Object.keys(scrollDepths).forEach(function(depth) {
if (scrollPercent >= depth && !scrollDepths[depth]) {
gtag('event', 'scroll', {
'percent_scrolled': depth,
'page_path': window.location.pathname
});
scrollDepths[depth] = true;
}
});
});
</script>
Video Interaction Tracking
Track video plays and completions:
<script>
document.querySelectorAll('video').forEach(function(video) {
let hasTrackedPlay = false;
video.addEventListener('play', function() {
if (!hasTrackedPlay) {
gtag('event', 'video_start', {
'video_title': document.title,
'video_url': this.currentSrc
});
hasTrackedPlay = true;
}
});
video.addEventListener('ended', function() {
gtag('event', 'video_complete', {
'video_title': document.title,
'video_url': this.currentSrc
});
});
});
</script>
Webflow Interactions Tracking
Track Webflow Interactions
Monitor Webflow's native interactions:
<script>
// Track Webflow interaction triggers
Webflow.push(function() {
$('.interaction-element').on('click', function() {
gtag('event', 'interaction_trigger', {
'interaction_name': $(this).data('interaction-name'),
'element_class': this.className
});
});
});
</script>
Modal/Lightbox Tracking
Track modal opens:
<script>
document.querySelectorAll('[data-lightbox]').forEach(function(trigger) {
trigger.addEventListener('click', function() {
gtag('event', 'lightbox_open', {
'lightbox_id': this.getAttribute('data-lightbox'),
'page_location': window.location.pathname
});
});
});
</script>
User Authentication Tracking
Member Login Tracking
For Webflow Memberships:
<script>
// Check if user is logged in
if (window.Webflow && window.Webflow.env('memberships')) {
gtag('event', 'login', {
'method': 'Webflow Memberships'
});
gtag('set', 'user_properties', {
'member_status': 'authenticated'
});
}
</script>
Troubleshooting
Tracking Code Not Loading
Issue: GA4 not collecting data
Solutions:
- Verify Measurement ID is correct (starts with G-)
- Check custom code was saved in Site Settings
- Ensure site is published after adding code
- Test on published site, not Webflow Designer
- Clear browser cache and test in incognito
- Check for JavaScript errors in console
Duplicate Page Views
Issue: Multiple page views per visit
Solutions:
- Check for duplicate GA4 code in site settings and page settings
- Remove GA4 from page-specific custom code if using site-wide
- Verify embed elements don't contain duplicate tracking
- Check for GTM also loading GA4
- Review third-party integrations
Ecommerce Events Not Firing
Issue: Product tracking not working
Solutions:
- Verify you're on a Webflow Ecommerce plan
- Test on published site with actual products
- Check product template custom code placement
- Verify Webflow dynamic binding syntax is correct
- Test events in GA4 DebugView
- Ensure JavaScript has no syntax errors
Custom Code Not Executing
Issue: Tracking code doesn't run
Solutions:
- Verify code is in correct location (Head vs Body)
- Check for script tag syntax errors
- Ensure code runs after DOM loads
- Test with simple console.log first
- Publish site after making changes
- Check browser console for errors
CMS Dynamic Binding Issues
Issue: Dynamic data not populating
Solutions:
- Use correct Webflow binding syntax:
{{wf {...} }} - Test binding on published site, not designer
- Verify field names match CMS collection
- Check that template context is correct
- Use plain text binding type for analytics values
Form Tracking Not Working
Issue: Form submissions not tracked
Solutions:
- Ensure form has unique name attribute
- Verify event listener attaches after DOM load
- Check form submission isn't prevented by other scripts
- Test with GA4 DebugView
- Verify form doesn't redirect immediately (preventing event)
Testing and Verification
Enable Debug Mode
Add to your GA4 configuration:
<script>
gtag('config', 'G-XXXXXXXXXX', {
'debug_mode': true
});
</script>
Test in Webflow Designer
Note: Tracking may not work fully in Designer preview. Always test on published site.
Complete Testing Checklist
- Page Views: Navigate between pages on published site
- Ecommerce: Add products, checkout, complete test purchase
- Forms: Submit test form submissions
- Custom Events: Trigger all custom tracked interactions
- Mobile: Test on mobile devices and breakpoints
Browser Console Validation
// Check if gtag is loaded
console.log(typeof gtag);
// View dataLayer
console.log(window.dataLayer);
// Manually test event
gtag('event', 'test_event', {'test': 'value'});
GA4 DebugView
- Enable debug mode in code
- Open GA4 and go to Admin > DebugView
- Interact with your Webflow site
- Verify all events appear correctly
- Check event parameters
Best Practices
Use Site-Wide Settings
For global tracking, always use Site Settings > Custom Code instead of individual page embeds.
Organize Custom Code
Add comments to identify different tracking sections:
<script>
// === GA4 Base Configuration ===
gtag('config', 'G-XXXXXXXXXX');
// === Ecommerce Tracking ===
// Product view tracking code...
// === Form Tracking ===
// Form submission tracking code...
</script>
Test Before Publishing
Always test tracking on a staging or development site before deploying to production.
Use Webflow's CMS Features
Leverage dynamic binding for automatic data population:
'item_name': '{{wf {"path":"name","type":"PlainText"\} }}'
Event Naming Conventions
Use consistent, descriptive event names:
// Good
gtag('event', 'product_click');
// Bad
gtag('event', 'click');