Carrd Analytics Implementation | OpsBlu Docs

Carrd Analytics Implementation

Technical guide for implementing analytics tracking on Carrd single-page sites using Head/Body code injection and Pro plan features.

Analytics Architecture on Carrd

Carrd builds single-page websites. Every Carrd site is one HTML document with sections rendered vertically. There is no client-side routing, no page transitions, and no dynamic content loading. When a user navigates a Carrd site, they scroll through sections on a single URL. This has direct implications for analytics: you get one page view per visit, and all engagement must be tracked through scroll depth, section visibility, or interaction events.

Code injection is available on Pro plans only ($9/year and up). Free plans have no custom code access. Pro plans expose two injection points: Head Code (inside <head>) and Body Code (before </body>). Both are site-wide -- there are no per-section code injection options.

Carrd outputs static HTML hosted on its CDN. Pages are lightweight (typically under 200KB) and load fast, meaning analytics scripts often account for a significant portion of the total page weight.


Installing Tracking Scripts

Head Code Injection

In the Carrd editor, click the gear icon (site settings) and navigate to the Head field under the Code section.

<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXX"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());
  gtag('config', 'G-XXXXXXX');
</script>

For GTM:

<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-XXXXXX');</script>

Body Code Injection

The Body field in Code settings injects before </body>:

<!-- GTM noscript -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXXX"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>

<!-- Facebook Pixel -->
<script>
  !function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){
  n.callMethod?n.callMethod.apply(n,arguments):n.queue.push(arguments)};
  if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
  n.queue=[];t=b.createElement(e);t.async=!0;t.src=v;s=b.getElementsByTagName(e)[0];
  s.parentNode.insertBefore(t,s)}(window,document,'script',
  'https://connect.facebook.net/en_US/fbevents.js');
  fbq('init', 'YOUR_PIXEL_ID');
  fbq('track', 'PageView');
</script>

Embed Elements for Inline Tracking

Carrd's Embed element (Pro plan) accepts HTML/JavaScript inline within the page layout. Use this for section-specific tracking when needed, though Head/Body injection is preferred for analytics:

<script>
  dataLayer.push({
    event: 'section_reached',
    section_name: 'contact_form'
  });
</script>

Data Layer Implementation

Since Carrd sites are single pages, the data layer focuses on section visibility and user interactions rather than page navigation.

Base Data Layer

<script>
  window.dataLayer = window.dataLayer || [];
  dataLayer.push({
    page_type: 'single_page',
    site_platform: 'carrd',
    total_sections: document.querySelectorAll('#sections > section, #sections > div').length
  });
</script>

Scroll Depth and Section Tracking

This is the primary engagement metric for single-page Carrd sites:

<script>
  (function() {
    var sections = document.querySelectorAll('#sections > section, #sections > div');
    var tracked = {};

    var observer = new IntersectionObserver(function(entries) {
      entries.forEach(function(entry) {
        if (entry.isIntersecting) {
          var index = Array.prototype.indexOf.call(sections, entry.target);
          var sectionId = entry.target.id || 'section_' + index;
          if (!tracked[sectionId]) {
            tracked[sectionId] = true;
            dataLayer.push({
              event: 'section_view',
              section_id: sectionId,
              section_index: index,
              sections_total: sections.length
            });
          }
        }
      });
    }, { threshold: 0.5 });

    sections.forEach(function(section) {
      observer.observe(section);
    });
  })();
</script>

Form Submission Tracking

Carrd's built-in forms submit via AJAX and redirect to a success URL or show an inline message. Track form submissions by intercepting the submit event:

<script>
  document.addEventListener('submit', function(e) {
    var form = e.target;
    if (form.tagName === 'FORM') {
      var formFields = Array.prototype.map.call(
        form.querySelectorAll('input:not([type="hidden"]), textarea, select'),
        function(el) { return el.name || el.type; }
      );
      dataLayer.push({
        event: 'form_submit',
        form_fields: formFields.join(','),
        form_action: form.action || 'inline'
      });
    }
  });
</script>

Button Click Tracking

Carrd uses button elements for CTAs. Track clicks on all buttons:

<script>
  document.addEventListener('click', function(e) {
    var btn = e.target.closest('a.button, button');
    if (btn) {
      dataLayer.push({
        event: 'cta_click',
        cta_text: btn.textContent.trim(),
        cta_url: btn.href || '',
        cta_section: btn.closest('section') ?
          btn.closest('section').id || 'unknown' : 'unknown'
      });
    }
  });
</script>

Common Issues

Free Plan Has No Code Injection

The most common implementation failure. Carrd free plans do not expose Head, Body, or Embed Code fields. Analytics requires a Pro plan at minimum ($9/year for Pro Lite, $19/year for Pro Standard, $49/year for Pro Plus).

Single Page Means One Page View

Standard Google Analytics reports show a single page per session with 100% bounce rate. This is technically correct for a one-page site. Use event-based tracking (section views, scroll depth, CTA clicks) as your primary engagement metrics instead of page views.

Embed Elements vs Head/Body Code

Embed elements render inline in the DOM at their placed position. If an Embed contains a tracking script, it fires when that section loads into view (if lazy-loaded) or on page load (if above the fold). Head/Body code always fires on page load regardless of scroll position.

Form Success Detection

Carrd forms that redirect to a thank-you URL work with standard destination-based conversion tracking. Forms that show an inline success message are harder to detect. Look for DOM mutations:

var formContainer = document.querySelector('form');
if (formContainer) {
  var mutationObs = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
      if (mutation.target.querySelector('.message.success, .formResponse')) {
        dataLayer.push({ event: 'form_success' });
      }
    });
  });
  mutationObs.observe(formContainer.parentElement, { childList: true, subtree: true });
}

Stripe Payment Tracking

Carrd Pro supports Stripe integration for payments. The Stripe checkout redirects to Stripe's hosted page, then back to a success URL on your Carrd site. Track conversions on the success URL, not through DOM events:

// On your success page/section
if (window.location.search.indexOf('session_id') > -1) {
  dataLayer.push({
    event: 'purchase',
    payment_method: 'stripe',
    session_id: new URLSearchParams(window.location.search).get('session_id')
  });
}

Platform-Specific Considerations

DOM Structure: Carrd wraps all content in #wrapper with sections inside #sections. Individual sections get auto-generated IDs or custom IDs set in the editor. Target sections using #sections > section or #sections > div.

No Dynamic Content: Carrd does not support dynamic content loading, API calls, or database-driven pages. All content is static HTML. This means no server-side personalization or dynamic data layer population -- everything must be client-side.

Performance Impact: Carrd sites are extremely lightweight. Adding Google Analytics (45KB) or GTM (80KB) can double the page weight. Consider lighter alternatives like Plausible (~1KB) or Fathom for sites where page speed is critical.

Custom Domains: Analytics tracking codes should use the custom domain (not the *.carrd.co subdomain) to avoid cross-domain issues. Carrd handles the domain mapping at the CDN level, so the tracking domain matches the visitor-facing URL.

Multi-Site Management: Carrd Pro plans allow multiple sites. Each site has independent code injection. There is no way to apply tracking code across all sites simultaneously -- each must be configured individually.

Mobile Rendering: Carrd uses responsive CSS for mobile layouts. The same HTML serves all devices. Section order remains identical between desktop and mobile, so section-based tracking produces consistent data across devices.