rapid-salesclerk-86901
03/17/2025, 8:42 PMrapid-salesclerk-86901
03/17/2025, 8:43 PMimport {
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 };
}
rapid-salesclerk-86901
03/17/2025, 8:43 PM'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;
}
rapid-salesclerk-86901
03/17/2025, 8:43 PM'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>
);
}
rapid-salesclerk-86901
03/17/2025, 8:44 PM'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)
})();
fresh-football-47124
fresh-football-47124
fresh-football-47124
fresh-football-47124
rapid-salesclerk-86901
03/18/2025, 7:17 PMrapid-salesclerk-86901
03/19/2025, 5:25 PM