Hello, We are investigating an experiment coverage...
# ask-questions
p
Hello, We are investigating an experiment coverage issue and would appreciate your help reviewing our implementation. Experiment Details • Experiment:
hide-delivery-threshold
• Traffic Allocation: 100% • Days Running: 2 • Experiment Coverage Reported: ~35.5% Issue The experiment is configured with 100% traffic allocation, however GrowthBook is reporting only ~35.5% coverage. We would like to understand whether there is anything in our implementation that could be causing exposures or assignments to be missed. Full Implementation
Copy code
<style>
  .shopify-section--announcement-bar,
  .product-info__free-shipping-text,
  [data-block-type='offer'] {
    display: none;
  }
</style>

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

  const __gbSeen = new Set();

  window.growthbook_queue.push(function (gb) {
    gb.setTrackingCallback(function (experiment, result) {
      const key = experiment.key + result.variationId;

      if (__gbSeen.has(key)) return;
      __gbSeen.add(key);

      window.dataLayer = window.dataLayer || [];
      window.dataLayer.push({
        event: 'experiment_viewed',
        experiment_id: experiment.key,
        variation_id: result.variationId,
      });

      console.log(
        'experiment_viewed fired:',
        experiment.key,
        result.variationId
      );
    });

    function runExperiment() {
      const hideDeliveryThreshold = gb.isOn(
        'hide-delivery-threshold'
      );

      console.log(
        'growthbook hide-delivery-threshold value:',
        hideDeliveryThreshold
      );

      const selectors = [
        '.shopify-section--announcement-bar',
        '.product-info__free-shipping-text',
        '.product-info__shipping-delivery-separator',
        '.product-info__free-shipping-threshold',
        '[data-block-type="offer"]',
      ];

      const elements = document.querySelectorAll(
        selectors.join(',')
      );

      if (hideDeliveryThreshold) {
        elements.forEach((el) => el.remove());
      } else {
        elements.forEach((el) => {
          el.style.display = 'block';
        });
      }
    }

    function init() {
      runExperiment();

      const productSection =
        document.querySelector('.shopify-section--main-product') ||
        document.querySelector('product-info') ||
        document.body;

      const observer = new MutationObserver((mutations) => {
        const variantPickerUpdated = mutations.some(
          (mutation) =>
            Array.from(mutation.addedNodes).some(
              (node) =>
                node.nodeType === 1 &&
                (
                  node.matches?.(
                    '[data-block-type="variant-picker"]'
                  ) ||
                  node.querySelector?.(
                    '[data-block-type="variant-picker"]'
                  )
                )
            )
        );

        if (variantPickerUpdated) {
          console.log(
            'Variant picker rerendered - re-running experiment'
          );

          runExperiment();
        }
      });

      observer.observe(productSection, {
        childList: true,
        subtree: true,
      });
    }

    if (document.readyState === 'loading') {
      document.addEventListener(
        'DOMContentLoaded',
        init
      );
    } else {
      init();
    }
  });
</script>
Additional Context • The experiment is intended to run site-wide. • We use
gb.isOn('hide-delivery-threshold')
to evaluate the experiment. • We use
setTrackingCallback
and send exposure events to GTM via
dataLayer.push()
. • We also re-run the experiment when the PDP variant picker is re-rendered. • We have observed that
experiment_viewed
events are firing in the browser console. Questions 1. Do you see anything in the implementation above that could cause experiment assignments or exposures to be missed? 2. Given 100% traffic allocation and ~35.5% coverage, what would be the recommended debugging steps to identify where assignments are being lost? Any help reviewing the implementation and identifying potential causes would be greatly appreciated. Thank you.
f
Hi @polite-quill-58663 There's nothing in your code that immediately suggests a bucketing issue, but the key thing to note is that 100% traffic allocation means 100% of users who are eligible and actually evaluate the experiment, not necessarily 100% of all site visitors. Since the exposure only fires when
gb.isOn('hide-delivery-threshold')
runs, ~35.5% coverage likely means the feature is only being evaluated for ~35.5% of users/sessions To begin, please can you share how you’re setting attributes for this SDK (especially the assignment attribute) and a screenshot of the feature’s rules in GrowthBook? That would help narrow down why only ~35.5% of users are ending up in the experiment despite 100% allocation. As we're using the User Slack please make sure to conceal any sensitive/personal information
p
Hi @flaky-noon-11399, Thanks for the response. I've attached a screenshot of the experiment configuration.
f
Please can you share a screenshot of the feature rukes so we can review the order?
p
@flaky-noon-11399 Let me know if this helps or if you need any additional information.
hi @flaky-noon-11399 any update ?
f
Hi @polite-quill-58663 apologies for the delay. Nothing in the screenshots suggests a GrowthBook configuration issue. If I had to bet, I'd suspect one of: 1. The code only runs on a subset of pages/users. 2. Many visitors do not have the
id
assignment attribute available when evaluation occurs. 3. Exposure events are being dropped between the browser and the warehouse. Can you confirm whether 100% of site visitors have the
id
attribute available when the feature is evaluated, and whether the
hide-delivery-threshold
code is loaded on every page or only specific page types (e.g. PDPs)? Those two items are the most common causes of seeing ~35% coverage on a 100% traffic experiment.
Are you using an activation metric on this experiment? If so, what is the activation event and what percentage of users typically trigger it? Also, is the 35.5% figure coming from the experiment results page, experiment health/coverage diagnostics, or from your own analytics?
p
hi @flaky-noon-11399 Question 1: Can you confirm whether 100% of site visitors have the
id
attribute available when the feature is evaluated?
id
attribute is sourced from a cookie named gbuuid. This is a UUID automatically generated and stored by GrowthBook's own SDK on first page load (e.g. ae5edb4a-0df4-49f8-bac0-6c32cb996fd3). Since gbuuid is a browser-side cookie. It is never sent to GA4 as an event parameter or user property, and therefore never exported to BigQuery. There is no column or field in our data warehouse that captures this value. It only exists in the visitor's browser at the time of the session and cannot be queried after the fact. But when checked on live site using
window._growthbook?.getAttributes()
below is the result
Copy code
{id: 'ae5edb4a-0df4-49f8-bac0-6c32cb996fd3', url: '<https://keralaayurveda.com/>', path: '/', host: '<http://keralaayurveda.com|keralaayurveda.com>', query: '', …}
browser: "chrome"
deviceType: "mobile"
host: "<http://keralaayurveda.com|keralaayurveda.com>"
id: "ae5edb4a-0df4-49f8-bac0-6c32cb996fd3"
pageTitle: "Authentic Ayurvedic Remedies | Kerala Ayurveda Since 1945"
path: "/"
query: ""
url: "<https://keralaayurveda.com/>"
Question 2: Whether the
hide-delivery-threshold
code is loaded on every page or only specific page types (e.g. PDPs)? The
hide-delivery-threshold
feature is evaluated on every page, not just PDPs. Question 3: Are you using an activation metric on this experiment? - None *Question 4:*The 35.5% figure is from our own analytics (GA4 → BigQuery)? - yes
f
Hi @polite-quill-58663, thanks, this is really helpful! Since the experiment is assigned using GrowthBook’s
id
/
gbuuid
, but that ID is not currently sent to GA4 or BigQuery, it would be worth testing this by passing the
gbuuid
with the
experiment_viewed
event temporarily. That should help confirm whether the experiment is being evaluated correctly in the browser, and whether the lower coverage number is coming from the GA4/BigQuery side. Once that’s in place, you can compare the
experiment_viewed
events against the
growthbook_id
values in BigQuery. If the browser is firing the event as expected but BigQuery still shows lower coverage, that would point more towards the GA4/GTM/BigQuery tracking path rather than GrowthBook assignment itself.
p
Hi @flaky-noon-11399, We found another issue during testing. When a user lands on the website and navigates between pages, the experiment does not appear to remain consistent. Within the same session, the user is being exposed to both the test variant and the control variant while navigating through the site. I've attached a screen recording for reference. In the recording, you can observe the announcement bar appearing and disappearing across page navigations for the same user session. Could you please help us understand what might cause this behavior ?
hi @flaky-noon-11399 any update on this
f
Hi @polite-quill-58663, thanks for sharing the recording — I can see what you mean with the bar appearing/disappearing as you move between pages. The first thing I’d check is whether the GrowthBook assignment ID is staying the same across those page navigations. If the
id
/
gbuuid
changes, or is missing on some page loads, GrowthBook may treat the same browser session as a different user and assign a different variation. Could you add a temporary debug log on each page load/navigation to confirm the ID and feature value? It may look something like this:
Copy code
console.log("GrowthBook debug", {
  url: window.location.href,
  id: gb.getAttributes()?.id,
  value: gb.isOn("hide-delivery-threshold")
});
Once added, please can you test this while navigating between the same pages shown in the recording. Ideally, the
id
should stay the same, and the feature value should also stay consistent for that same ID. If either changes, that would explain the behaviour and we can then narrow down whether the issue is cookie/consent-related, SDK loading timing, or attributes not being available consistently.
p
Hi @flaky-noon-11399, I tested this by adding the debug log you suggested while navigating through the site. The
id
remains consistent across all page navigations, however the feature value returned by
gb.isOn("hide-delivery-threshold")
changes for the same
id
. Example:
Copy code
Home
id: ae5edb4a-0df4-49f8-bac0-6c32cb996fd3
value: true

PDP
id: ae5edb4a-0df4-49f8-bac0-6c32cb996fd3
value: false
So the assignment ID is stable, but the evaluated feature value is not, which results in the user seeing both the test and control experiences within the same session. I've also attached a screen recording that demonstrates this behavior. In the video, you can see the announcement bar appearing and disappearing while navigating between pages, even though the GrowthBook ID remains unchanged.
hey @flaky-noon-11399 any update on this?
f
Hi @polite-quill-58663, thanks for the recording and logs — this is helpful. If the
id
stays the same but
gb.isOn("hide-delivery-threshold")
changes between Home and PDP, that points away from the assignment ID and more towards different targeting/attributes, SDK config, or timing between pages. Could you please check the feature in GrowthBook using Test Feature Rules with the exact attributes from Home and PDP? Use the same
id
, but also include the URL/path and any other attributes you pass into GrowthBook, so we can see which rule is matching on each page. I’d also check: • Home and PDP are using the same SDK connection/client key • The same feature payload is loaded on both pages • Attributes are fully set before
gb.isOn()
is called • There are no URL/path/page-type targeting rules causing the user to enter the experiment on one page but fall through to the default on another The tracking callback and DOM logic look okay from what you shared. The key thing to debug is why the feature evaluation result changes for the same ID across pages.