Hey guys, We have a redirect experiment targeting...
# ask-questions
r
Hey guys, We have a redirect experiment targeting https://buy.rugietmen.com/b2l/ and the variant is https://www.rugiet.com/bm/n1. When I am bucketed into the control, experiment_viewed shows but when I am bucketed into the variant, this does not come up in my GA4 debugger. Adding what we used for each SDK below:
rugiet.com
Copy code
import {
  configureCache,
  GrowthBook,
  setPolyfills,
} from '@growthbook/growthbook';

import type { Options } from '@growthbook/growthbook';
type GrowthBookInstanceOptions = Omit<Options, 'apiHost' | 'clientKey'>;

export function growthBookInstance(options?: GrowthBookInstanceOptions) {
  return new GrowthBook({
    apiHost: process.env.NEXT_PUBLIC_GROWTHBOOK_API_HOST,
    clientKey: process.env.NEXT_PUBLIC_GROWTHBOOK_CLIENT_KEY,
    ...options,
  });
}

export default async function initGrowthBook(
  options?: GrowthBookInstanceOptions,
) {
  setPolyfills({
    fetch: (
      url: Parameters<typeof fetch>[0],
      opts: Parameters<typeof fetch>[1],
    ) =>
      fetch(url, { ...opts, next: { revalidate: 60, tags: ['growthbook'] } }),
  });

  configureCache({ disableCache: true });

  /**
   * 1. gb.init();
   * 2. gb.setAttributes()
   * 3. gb.isOn()
   * 4. gb.getFeatureValue()
   * 5. gb.getDeferredTrackingCalls()
   * 6. gb.getDecryptedPayload()
   * 7. gb.destroy()
   */
  const gb = growthBookInstance({ ...options });

  const { error } = await gb.init({ timeout: 1000 });

  if (error) {
    console.error(error);
  }

  const payload = gb.getDecryptedPayload();
  const trackingData = gb.getDeferredTrackingCalls();

  gb.destroy();

  return { payload, trackingData };
}
Copy code
'use client';
import { useEffect } from 'react';

import { sendGTMEvent } from '@next/third-parties/google';

import type { TrackingCallback, TrackingData } from '@growthbook/growthbook';

export const onExperimentView: TrackingCallback = (experiment, result) => {
  sendGTMEvent({
    event: 'experiment_viewed',
    experimentId: experiment?.key ?? '',
    variationId: result?.key ?? '',
  });
};

// Helper component to track experiment views from server components
export function GrowthBookTracking({ data }: { data: TrackingData[] }) {
  useEffect(() => {
    data.forEach(({ experiment, result }) => {
      onExperimentView(experiment, result);
    });
  }, [data]);

  return null;
}
Copy code
'use client';

import { useMemo, type PropsWithChildren } from 'react';

import { autoAttributesPlugin } from '@growthbook/growthbook/plugins';
import { GrowthBookProvider } from '@growthbook/growthbook-react';

import { growthBookInstance } from '../lib/growthbook';
import { onExperimentView } from '../lib/GrowthBookTracking';

import type { GrowthBookPayload } from '@growthbook/growthbook-react';

export default function GBookProvider({
  children,
  payload,
}: PropsWithChildren<{ payload: GrowthBookPayload }>) {
  const isWindowDefined = typeof window !== 'undefined';
  const growthBook = useMemo(
    () =>
      growthBookInstance({
        enableDevMode: true,
        ...(isWindowDefined ? { plugins: [autoAttributesPlugin()] } : {}),
        // Only required for A/B testing
        // Called every time a user is put into an experiment
        trackingCallback: (experiment, result) => {
          onExperimentView(experiment, result);
        },
      }).initSync({
        payload,
        streaming: true,
      }),
    [isWindowDefined, payload],
  );
  return (
    <GrowthBookProvider growthbook={growthBook}>{children}</GrowthBookProvider>
  );
}
buy.rugietmen.com
Copy code
'use strict';

window.gbRecordEvent = function(eventParams) {
  if (window.gtag) {
    window.gtag('event', 'experiment_viewed', eventParams)
    return;
  }
  window.dataLayer = window.dataLayer || [];
  window.dataLayer.push({
    event: 'experiment_viewed',
    experiment_id: eventParams.experiment_id,
    variation_id: eventParams.variation_id,
  });
};

(function() {
  if ('localStorage' in window) {
    var gbtlsRaw = localStorage.getItem('gbtls');
    try {
      if (gbtlsRaw) {
        var gbtls = JSON.parse(gbtlsRaw);
        if (gbtls.event && gbtls.date && new Date().getTime() - gbtls.date < 60000) {
          window.gbRecordEvent(gbtls.event);
        }
        localStorage.removeItem('gbtls');
      }
    } catch (e) {
      // ignore errors
    }
  }
})();

window.growthbook_config = window.growthbook_config || {};
window.growthbook_config.trackingCallback = function(experiment, result) {
  var eventParams = {
    experiment_id = experiment.key,
    variation_id = result.key,
  };

  window.gbRecordEvent(eventParams);
  if (result.inExperiment && 'urlPatterns' in experiment) {
    if ('localStorage' in window) {
      localStorage.setItem('gbtls', JSON.stringify({
        ref: window.location.href,
        date: new Date().getTime(),
        event: eventParams
      }));
    }
  }
};

(function(s) {
  s=document.createElement('script'); s.async=true;
  s.dataset.clientKey='sdk-sFuEq2PPFWRjYyH';
  s.dataset.apiHost='<https://cro-lab.novapower.io:3100>';
  s.src='<https://cdn.jsdelivr.net/npm/@growthbook/growthbook/dist/bundles/auto.min.js>';
  document.head.appendChild(s)
})();
f
hi Caleb
when we redirect, we try to fire the trackingCallback before the redirect happens
ah, I see your code also trys to fire the event before and after
I wonder if the issue is that as you're setting the local storage on the buy.rugietmen.com domain, but not checking for it on the other domain
r
Great insight, I'll see if adding that in helps
Confirming that passing the experiment_id and variation_id as query params and forcing an experiment_viewed event worked!