Skip to main content

HTML Script Tag SDK

We provide an HTML <script> tag option for easily integrating GrowthBook into any website.

This option is quick and straightforward to use and does not require coding knowledge to implement.

Installation

For this, you will need a Client Key from an SDK Connection within GrowthBook. This will start with sdk-.

Add the following script tag to your website and replace YOUR_CLIENT_KEY_HERE with your actual Client Key:

<script async
data-client-key="YOUR_CLIENT_KEY_HERE"
src="https://cdn.jsdelivr.net/npm/@growthbook/growthbook/dist/bundles/auto.min.js"
></script>

Or, if you can't add data-* attributes (e.g. in Google Tag Manager), you can use this alternate version:

<script>
(function(s) {
s=document.createElement('script'); s.async=true;
s.dataset.clientKey="YOUR_CLIENT_KEY_HERE";
s.src="https://cdn.jsdelivr.net/npm/@growthbook/growthbook/dist/bundles/auto.min.js";
document.head.appendChild(s);
})();
</script>

For best performance, we recommend adding this script tag directly before the closing </head> tag, however it is also possible to load through something like Google Tag Manager if that is your only option.

Optional Configuration Settings

Besides the Client Key, there are some additional settings you can define with data- attributes on the script tag:

  • data-api-host - Defaults to GrowthBook Cloud's https://cdn.growthbook.io. This must be set to your own domain instead if self-hosting or using the GrowthBook Proxy.
  • data-decryption-key - Required if you enabled encryption in your SDK Connection settings in GrowthBook

All other settings can be defined with a window.growthbook_config object BEFORE you load the script tag. This accepts the same settings as our JavaScript SDK. Here's an example:

<script>
window.growthbook_config = window.growthbook_config || {};
// Disable streaming updates
window.growthbook_config.backgroundSync = false;
</script>

If you need low level access to the GrowthBook SDK instance for any reason, you can use a callback function. This will be called as soon as the GrowthBook SDK instance is ready. If you push to the queue after GrowthBook has already loaded, the callback will be invoked immediately.

<script>
window.growthbook_queue = window.growthbook_queue || [];
window.growthbook_queue.push((gb) => {
// Do whatever you need with the GrowthBook instance here
console.log(gb.getAttributes());
})
</script>

Targeting Attributes

The following targeting attributes are set automatically and available for use.

  • id - creates a long-lived gbuuid cookie if it doesn't exist already
  • url
  • path
  • host
  • query
  • pageTitle
  • deviceType - either mobile or desktop
  • browser - one of chrome, edge, firefox, safari, or unknown
  • utmSource
  • utmMedium
  • utmCampaign
  • utmTerm
  • utmContent

In addition, if you use Google Tag Manager, any variables you set in your Data Layer will also be set here and available for targeting.

Adding Custom Attributes

You can include your own custom attributes by adding the following BEFORE the GrowthBook snippet:

<script>
window.growthbook_config = window.growthbook_config || {};
window.growthbook_config.attributes = {
country: "US",
otherCustomAttribute: 12,
}
</script>

You can also set custom attributes later, after the script tag has been added. Please note, this may cause flickering in your experiments if you reference these custom attributes in your experiment targeting.

<script>
window.growthbook_queue = window.growthbook_queue || [];
window.growthbook_queue.push((gb) => {
gb.updateAttributes({
country: "US",
otherCustomAttribute: 12,
});
});
</script>

Refreshing Auto Attributes

The GrowthBook snippet will automatically watch for URL changes and update attributes when that happens. If you would like more control over this behavior, you can manually trigger updates at any time by firing a growthbookrefresh event from JavaScript. For example:

document.dispatchEvent(new CustomEvent("growthbookrefresh"));

Tracking Experiment Views

When a user views an experiment, a tracking event is fired. There is built-in support for Segment.io (analytics.js), GA4 (gtag), and Google Tag Manager (dataLayer).

Segment.io

GrowthBook will automatically fire an event using window.analytics.track if it's present on the page. The event name is Experiment Viewed and it has two properties: experiment_id and variation_id.

There is no additional configuration needed.

GA4 (gtag)

GrowthBook will automatically fire an event using Google Analytic 4's window.gtag if it's present on the page. The event name is experiment_viewed and it has two properties: experiment_id and variation_id.

There is no additional configuration needed.

Google Tag Manager

We send the following event to the Data Layer. You will need to add a trigger based on this and forward it on to your analytics tool of choice.

{
"event": "experiment_viewed",
"experiment_id": "...",
"variation_id": "..."
}

We have a walkthrough tutorial on how to configure this in our GTM Guide

Mixpanel

To work with Mixpanel, we have to set the ID as an attribute for GrowthBook, and also add the custom event tracking callback. Below is an example of how to set up GrowthBook with Mixpanel. The script initializes Mixpanel (which you probably already have) and then sets the Mixpanel distinct ID to a GrowthBook id attribute once it has loaded. Then the script defines a trackingCallback to log the experiment exposure event to Mixpanel.

<script>
window.growthbook_config = window.growthbook_config || {};
mixpanel.init("[YOUR PROJECT TOKEN]", {
debug: true,
loaded: function (mx) {
window.growthbook_queue = window.growthbook_queue || [];
window.growthbook_queue.push((gb) => {
gb.setAttributes({
...gb.getAttributes(),
id: mx.get_distinct_id(),
});
})
},
});
window.growthbook_config.trackingCallback = (experiment, result) => {
mixpanel.track("$experiment_started", {
"Experiment name": experiment.key,
"Variant name": result.variationId,
$source: "growthbook",
});
</script>
<!-- then load the GrowthBook SDK -->
<script async
data-client-key="YOUR_CLIENT_KEY_HERE"
src="https://cdn.jsdelivr.net/npm/@growthbook/growthbook/dist/bundles/auto.min.js"
></script>

Others

For any other event tracking system (or if the built-in ones above do not meet your requirements), you can define your own custom tracking callback function. This must be defined BEFORE loading the main GrowthBook snippet on the page.

<script>
window.growthbook_config = window.growthbook_config || {};
window.growthbook_config.trackingCallback = (experiment, result) => {
customEventTracker("Viewed Experiment", {
experiment_id: experiment.key,
variation_id: result.key
})
};
</script>

Sticky Bucketing

This SDK supports Sticky Bucketing, but it is disabled by default. To enable, add the following to your script tag:

data-use-sticky-bucket-service="cookie"

There are 2 possible values:

  • cookie - Persist in a cookie that is shared between the browser and your server
  • localStorage - Persist in the browser's localStorage, which is never sent to your server

You can also customize the key we use to store sticky buckets by adding a prefix:

data-sticky-bucket-prefix="my_prefix"

Using Feature Flags

You can use feature flags with this SDK, but it does require some manual coding work. Here is an example:

<script>
// Wait for the GrowthBook SDK to load before running
window.growthbook_queue = window.growthbook_queue || [];
window.growthbook_queue.push((gb) => {
// Function that uses feature flags to make changes to the page
const applyFeatureFlags = () => {
if(gb.isOn("dark-mode")) {
document.documentElement.classList.add("dark");
} else {
document.documentElement.classList.remove("dark");
}
}

// Call your function initially plus whenever new data is received
applyFeatureFlags();
document.addEventListener("growthbookdata", applyFeatureFlags)
});
</script>

By default, this SDK persists a random unique identifier in a first-party cookie named gbuuid. This cookie is required to provide a consistent user experience to your visitors. Without this cookie, if you run an A/B test, a visitor might be re-bucketed into a different variation every time they visit your website.

The gbuuid cookie does not contain any Personally Identifiable Information (it's just a randomly generated id). It is a first-party cookie that is never shared with any third-party services, not even GrowthBook itself. However, we still recommend adding this to your site's cookie policy if you have one.

If you must delay persisting the gbuuid cookie until a user consents, you can add a data-no-auto-cookies attribute to the script tag.

This will still generate a UUID for the user, but will not persist it. That means, if the user refreshes the page, they will have a new random UUID generated.

You have the option to manually persist this cookie at any time, for example when a user grants consent on your cookie banner. All you need to do is fire this custom event from javascript:

document.dispatchEvent(new CustomEvent("growthbookpersist"));

Content Security Policy (CSP)

If your site uses a Content Security Policy, you may need to make a few changes to the script-src directive for this SDK to load and run on your site.

First, make sure to add https://cdn.jsdelivr.net so the script itself can load. If this isn't possible, you can save the contents of the script and host it on your own domain instead. Just note that doing that means you will no longer get automatic updates when we make improvements to the script tag.

Second, if you plan to use the Visual Editor to inject custom javascript into your site, you need to allow both usafe-inline and unsafe-eval. If this isn't possible, we have an alternative using nonces (see below).

Using Script Nonces

As an alternative to allowing unsafe-inline, we support "nonces", although this requires some very technical and custom configuration to hook up. This is only required if you plan to use the Visual Editor to inject custom javascript into your site.

You will still need to allow usafe-eval due to how our Visual Editor works under-the-hood.

First, you will need to generate a unique nonce value for every request and add it to your CSP header. This can be done on the edge such as with a Cloudflare Worker.

Lastly, you will also need to inject the following into your page's <head> BEFORE you load the GrowthBook snippet. This can be accomplished in the same edge worker. Replace all instances of $NONCE with the unique nonce value you generated.

<script nonce="$NONCE">
window.growthbook_config = window.growthbook_config || {};
window.growthbook_config.jsInjectionNonce = "$NONCE";
</script>