Skip to main content
6 min read

Webflow Integration

Add Zenovay to any Webflow site in under three minutes. Webflow's first-class Custom Code support makes this one of the cleanest integrations of any CMS — paste, publish, done.

Webflow Custom Code requires a paid Site Plan (Basic, CMS, Business, or Ecommerce) on the site itself. Workspace plans alone are not enough.


Quick Start

StepWhereWhat you do
1Zenovay dashboardCopy your tracking snippet
2Webflow Designer → Site settings → Custom codePaste it into Head code
3Publish to your *.webflow.io or custom domainClick Publish
4Zenovay dashboardReal-time visitors appear within ~30 seconds

Webflow lets you inject HTML into the <head> of every page on your site through Site Settings. This is the supported approach for any analytics or marketing pixel.

Step-by-step

  1. Open your project in the Webflow Designer.
  2. Click the gear icon in the left sidebar to open Site Settings.
  3. Go to the Custom Code tab.
  4. In the Head code box, paste:
<script defer data-tracking-code="YOUR_TRACKING_CODE" src="https://api.zenovay.com/z.js"></script>
  1. Scroll down and click Save Changes.
  2. Return to the Designer and click Publish (top right) → select your domains → Publish to Selected Domains.

Verify

Open your published site in incognito and view source — you should see the <script defer data-tracking-code=...> near the top of <head>. Your visit should appear in the Zenovay real-time view within 30 seconds.


Method 2: Page-specific Custom Code

If you only want to track a subset of pages (e.g. landing pages, not the docs subdirectory), Webflow supports per-page Head code:

  1. In the Designer, select the page in the left Pages panel.
  2. Click the gear icon next to the page name → Page Settings.
  3. Scroll to Custom Code → Inside <head> tag.
  4. Paste the same snippet there.
  5. Save and Publish.

Page-level Custom Code is appended after Site-wide code, so if you paste in both places you'll double-count. Pick one scope.


Tracking custom events

After the script loads (it's deferred, so wait for DOMContentLoaded), you can call window.zenovay() from any inline script or Webflow interactions custom code:

Track a CTA click

Drop a HTML Embed element next to your CTA button:

<script>
  document.addEventListener('DOMContentLoaded', () => {
    const cta = document.querySelector('[data-zv-cta]');
    if (!cta) return;
    cta.addEventListener('click', () => {
      if (window.zenovay) {
        window.zenovay('track', 'cta_clicked', {
          location: cta.dataset.zvCta,
          page: window.location.pathname,
        });
      }
    });
  });
</script>

Then add data-zv-cta="hero-primary" to your button in the Designer (via the Custom attributes section in element settings).

Track form submissions

Webflow native forms emit a submit event you can listen for:

<script>
  document.addEventListener('DOMContentLoaded', () => {
    document.querySelectorAll('form[data-name]').forEach(form => {
      form.addEventListener('submit', () => {
        if (window.zenovay) {
          window.zenovay('track', 'form_submitted', {
            form_name: form.getAttribute('data-name'),
            page: window.location.pathname,
          });
        }
      });
    });
  });
</script>

Identify logged-in users (Memberstack, Outseta, Memberspace)

If you use a Webflow membership add-on, identify the visitor as soon as their session is known. With Memberstack:

<script>
  window.$memberstackDom?.getCurrentMember().then(({ data: member }) => {
    if (member && window.zenovay) {
      window.zenovay('identify', {
        userId: member.id,
        email: member.auth?.email,
        plan: member.planConnections?.[0]?.planName,
      });
    }
  });
</script>

Tracking Webflow Ecommerce

If you sell through Webflow Ecommerce, fire a purchase event on the order confirmation page (/order-confirmation/[order-id]):

  1. Add an HTML Embed to your Order Confirmation page template.
  2. Paste:
<script>
  document.addEventListener('DOMContentLoaded', () => {
    const total = document.querySelector('[data-wf-order-total]')?.textContent;
    const orderId = window.location.pathname.split('/').pop();
    if (window.zenovay && total) {
      window.zenovay('track', 'purchase', {
        transaction_id: orderId,
        revenue: parseFloat(total.replace(/[^0-9.]/g, '')),
        currency: 'USD', // adjust if your store uses another currency
      });
    }
  });
</script>

For high-accuracy revenue attribution (refunds, taxes, subscriptions), use server-side webhooks into Zenovay from your Stripe or Webflow Ecommerce account instead — client-side tracking can miss orders if the buyer closes the tab.


Plan requirements

  • Webflow Starter (free): Custom Code is disabled. Upgrade to a paid Site Plan.
  • Webflow Basic / CMS / Business / Ecommerce: Custom Code is fully enabled.
  • Workspace plan only: not sufficient on its own — you need a Site Plan on the actual site.

Common gotchas

Site Settings vs Page Settings. Site-wide Head code applies to every page including 404, search, and password pages. Page-specific Head code only applies to that page. If you want one tracker for the whole site, use Site Settings — don't mix scopes.

Webflow strips <script> tags in .webflow.io previews if your plan doesn't include Custom Code. Make sure you're on a paid Site Plan before testing.

The snippet runs after Webflow's interactions. Zenovay is deferred, so it loads after the initial render. This is intentional — it means we don't block paint. If you want to fire an event before Zenovay loads, queue it: window.zenovay = window.zenovay || function(){ (window.zenovay.q = window.zenovay.q || []).push(arguments); };

<script> inside HTML Embed elements gets executed. Webflow allows it, but be aware that this means you can accidentally double-install if you paste the snippet into an Embed instead of Site Settings → Custom Code. Use Site Settings for the tracker; use Embeds only for page-specific event tracking.

Webflow's published HTML is heavily cached at the edge. Allow 1–2 minutes after Publish before testing. Force-refresh with Cmd/Ctrl+Shift+R.


Troubleshooting

SymptomLikely causeFix
No dataCustom Code disabled on planUpgrade to a paid Site Plan
No dataSite not published since adding the snippetClick Publish in the Designer
Half the pages trackedPage-level Head code overriding Site-levelMove snippet to Site Settings only
Double pageviewsSnippet pasted in Site Settings and HTML EmbedRemove one
Events not firingCustom event script ran before Zenovay loadedWrap in DOMContentLoaded

Privacy & compliance

Add data-cookieless="true" to the snippet to run in fully cookieless mode (no cookies, no local storage) — required for many EU/UK deployments before any consent is recorded:

<script defer
        data-tracking-code="YOUR_TRACKING_CODE"
        data-cookieless="true"
        src="https://api.zenovay.com/z.js"></script>

See Privacy Compliance for the full breakdown.



Need help? Contact [email protected] or visit our Help Center.

Was this page helpful?