Bookmark Analytics Implementation | OpsBlu Docs

Bookmark Analytics Implementation

Technical guide for implementing analytics tracking on Bookmark sites using code injection areas, embed blocks, and AiDA-generated pages.

Analytics Architecture on Bookmark

Bookmark is an AI-driven website builder where sites are generated through the AiDA (Artificial Intelligence Design Assistant) system. AiDA produces multi-page sites from user questionnaire responses. The generated pages use Bookmark's proprietary template engine, rendering static HTML with Bookmark's JavaScript framework for interactive elements.

Analytics code injection happens at the site level through Bookmark's settings panel. There is no template-level or page-level code injection -- all custom code applies globally. Bookmark does not expose raw template files or allow server-side modifications. Developer access is limited to what the platform's settings UI provides.

Pages load as traditional multi-page sites. Each page is a full HTML document served from Bookmark's CDN. There is no SPA routing or client-side navigation between pages.


Installing Tracking Scripts

Site-Wide Code Injection

Navigate to Settings > Custom Code (or Settings > SEO > Header/Footer Code depending on plan version). Bookmark provides two injection points:

Header Code (renders in <head>):

<!-- Google Tag Manager -->
<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>

Footer Code (renders 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>

Google Analytics via Built-In Integration

Bookmark offers a direct Google Analytics field under Settings > Analytics. Enter the Measurement ID:

G-XXXXXXXXXX

Bookmark auto-injects the gtag.js snippet. This is the simplest method but provides no control over configuration:

<!-- What Bookmark injects automatically -->
<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');
</script>

If you need custom configuration (enhanced measurement toggling, consent mode, custom dimensions), use GTM through the Custom Code injection instead.

Embed Blocks for Inline Code

Add an Embed or Custom HTML block to any page section in the editor:

<script>
  // Track this section's visibility
  var observer = new IntersectionObserver(function(entries) {
    entries.forEach(function(entry) {
      if (entry.isIntersecting) {
        window.dataLayer = window.dataLayer || [];
        dataLayer.push({
          event: 'section_view',
          section_name: 'testimonials'
        });
        observer.disconnect();
      }
    });
  }, { threshold: 0.5 });
  observer.observe(document.currentScript.parentElement);
</script>

Data Layer Implementation

Bookmark does not provide a native data layer. Build one in the Header Code injection:

<script>
  window.dataLayer = window.dataLayer || [];

  // Parse page information from Bookmark's DOM
  var path = window.location.pathname;
  var pageType = 'content';
  if (path === '/' || path === '/index.html') pageType = 'home';
  if (path.indexOf('/blog') === 0) pageType = 'blog';
  if (path.indexOf('/store') === 0 || path.indexOf('/shop') === 0) pageType = 'shop';

  dataLayer.push({
    page_type: pageType,
    page_path: path,
    page_title: document.title,
    platform: 'bookmark'
  });
</script>

E-Commerce Tracking

Bookmark's built-in store renders product data in the DOM. Extract it for e-commerce data layer events:

<script>
  document.addEventListener('DOMContentLoaded', function() {
    // Product page detection
    var productTitle = document.querySelector('.product-title, [data-product-name]');
    var productPrice = document.querySelector('.product-price, [data-product-price]');

    if (productTitle && productPrice) {
      dataLayer.push({
        event: 'view_item',
        ecommerce: {
          items: [{
            item_name: productTitle.textContent.trim(),
            price: parseFloat(productPrice.textContent.replace(/[^0-9.]/g, ''))
          }]
        }
      });
    }
  });
</script>

Add to Cart Tracking

document.addEventListener('click', function(e) {
  var addToCartBtn = e.target.closest('[class*="add-to-cart"], [class*="addToCart"]');
  if (addToCartBtn) {
    var container = addToCartBtn.closest('[class*="product"]');
    var name = container ? container.querySelector('[class*="title"], [class*="name"]') : null;
    var price = container ? container.querySelector('[class*="price"]') : null;
    dataLayer.push({
      event: 'add_to_cart',
      ecommerce: {
        items: [{
          item_name: name ? name.textContent.trim() : 'unknown',
          price: price ? parseFloat(price.textContent.replace(/[^0-9.]/g, '')) : 0
        }]
      }
    });
  }
});

Common Issues

AiDA Regeneration Overwrites Embed Blocks

When using AiDA to regenerate or significantly modify your site, custom HTML/Embed blocks may be removed or repositioned. Always re-audit embed-based tracking after any AiDA operation. Site-wide Header/Footer Code injections survive AiDA changes.

Custom Code Requires Paid Plan

Free Bookmark plans restrict or entirely block custom code injection. The Custom Code fields in Settings are only available on paid plans. Verify plan-level access before attempting implementation.

DOM Class Names Are Not Stable

Bookmark's template engine generates class names that can change between site rebuilds or template updates. Do not rely on specific class selectors for long-term tracking. Use broader selector strategies:

// Fragile - class names may change
document.querySelector('.bm-product-card-v2__title');

// More robust - use attribute selectors or structural queries
document.querySelector('[data-product-name]');
// Or structural
document.querySelector('.product-title, [class*="product"] [class*="title"]');

Facebook Pixel and Bookmark's Social Integration

Bookmark has a built-in Facebook integration for social sharing. This does not include the Facebook Pixel. You must install the Pixel separately through Custom Code. The built-in social integration and the tracking Pixel are independent systems.

Bookmark Analytics Dashboard Conflict

Bookmark includes its own analytics dashboard showing page views and visitor stats. This internal tracking runs independently from any custom analytics you add. Numbers will differ between Bookmark's dashboard and Google Analytics due to different tracking methodologies and bot filtering.


Platform-Specific Considerations

Custom Domains: Bookmark supports custom domains on paid plans. Ensure your analytics property is configured for the custom domain, not the *.bookmark.com subdomain. Cross-domain tracking is needed if you use both.

Blog Tracking: Bookmark's built-in blog generates pages under a /blog/ path. Blog posts render as individual pages, each loading Header/Footer Code independently. Track blog-specific metrics:

if (window.location.pathname.indexOf('/blog') === 0) {
  var articleTitle = document.querySelector('h1, .blog-title, [class*="blog"] [class*="title"]');
  dataLayer.push({
    content_type: 'blog_post',
    article_title: articleTitle ? articleTitle.textContent.trim() : document.title
  });
}

Contact Form Tracking: Bookmark forms submit through the platform's backend. Listen for click events on submit buttons rather than form submission events:

document.addEventListener('click', function(e) {
  var submitBtn = e.target.closest('button[type="submit"], input[type="submit"], [class*="submit"]');
  if (submitBtn && submitBtn.closest('form')) {
    dataLayer.push({
      event: 'form_submit_attempt',
      form_page: window.location.pathname
    });
  }
});

Mobile Rendering: Bookmark sites are responsive. The same HTML serves all viewports. No separate mobile site or mobile-specific code injection exists.

SSL/HTTPS: All Bookmark sites serve over HTTPS. Ensure all tracking endpoints use HTTPS to avoid mixed content warnings that block script execution.

Page Load Performance: AiDA-generated sites include Bookmark's framework JavaScript (~150-300KB). Adding analytics on top of this increases total script payload. Load analytics scripts asynchronously and use the Footer Code injection for non-critical tracking to minimize impact on visible content rendering.