Standalone Loading
Load Ours Privacy experimentation as a standalone script without daisy-chaining through the CDP. Full snippet, visitor identity options, flicker prevention, and GTM Custom HTML setup.
Standalone Loading
The standard installation loads experiments through the Ours Privacy Web SDK or Tag Manager. Both daisy-chain the experiment script: the CDP loads first, then fetches and initializes the experiment runtime. This works well but adds latency — especially through Google Tag Manager, where the chain is GTM → CDP → experiments.
If you want the fastest possible experiment evaluation with no flicker, load the experiment script directly. The CDP still powers identity and event tracking underneath — you are just loading the experiment script yourself instead of letting the CDP inject it.
When to Use Standalone Loading
| Scenario | Recommended Approach |
|---|---|
| Already running the Ours Web SDK | Use the standard installation — add experimentation.token to your init call |
| Already running Ours Tag Manager | Use the Tag Manager init tag — add the experiment token in the tag config |
| Running the CDP via GTM but seeing flicker | Use standalone loading for the experiment script, keep the CDP in GTM for tracking |
| Want direct control over script loading order | Use standalone loading (this page) |
init() Options
Call window.ours_experiments.init(options) after the experiment script loads. This starts experiment evaluation.
| Option | Type | Required | Description |
|---|---|---|---|
visitorId | string | Yes | The Ours CDP visitor ID. Must match the identity the CDP uses so experiment assignments, impressions, and conversions are all linked. |
Resolving the visitor ID
The Ours CDP stores the visitor ID in a cookie and localStorage under the key ours_device_id. You can read it synchronously — no need to wait for the CDP to initialize. If the visitor is new (no stored ID yet), generate a UUID and write it to both locations. When the CDP loads later, it checks these same locations first, so it will adopt the ID you created.
<script>
var key = 'ours_device_id';
var id = localStorage.getItem(key);
if (!id) {
var match = document.cookie.match(new RegExp('(?:^|; )' + key + '=([^;]+)'));
id = match ? match[1] : null;
}
if (!id) {
id = crypto.randomUUID();
localStorage.setItem(key, id);
document.cookie = key + '=' + id + '; path=/; max-age=31536000';
}
window.ours_experiments.init({ visitorId: id });
</script>This runs synchronously, so experiments evaluate immediately with no flicker — even for first-time visitors.
Custom cookie name: If your CDP init uses a custom
cookie_names.device_id, replace'ours_device_id'with that value.
Impression and Conversion Tracking
The experiment runtime tracks impressions and conversions by calling window.ours('track', ...) — the Ours CDP SDK. As long as the CDP pixel snippet is on the page, these events flow into the Ours Privacy dashboard automatically.
The CDP pixel snippet creates a queuing stub immediately (before main.js finishes loading), so impression events fired by the experiment runtime are queued and flushed once the CDP is fully initialized. No events are lost.
This gives you:
$experiment_impressionevents when variants are assigned$experiment_conversionevents when you calltrackConversion()- Full experiment results in the dashboard with Bayesian analysis
Google Tag Manager (Custom HTML)
If you use Google Tag Manager but do not want to daisy-chain through the Ours CDP tag, add a Custom HTML tag that fires on All Pages with a Page View trigger.
Set the tag priority higher than other tags (e.g., priority 100) so it fires first, or use the Tag Sequencing feature to ensure it runs before your other tags.
<!-- GTM Custom HTML Tag: Ours Experiments (Standalone) -->
<script>
(function () {
if (window.ours_experiments && typeof window.ours_experiments.init === 'function') {
return;
}
var script = document.createElement('script');
script.src = 'https://cdn.oursprivacy.com/experiment-init?token=YOUR_EXPERIMENT_TOKEN';
script.onload = function () {
var key = 'ours_device_id';
var id = localStorage.getItem(key);
if (!id) {
var match = document.cookie.match(new RegExp('(?:^|; )' + key + '=([^;]+)'));
id = match ? match[1] : null;
}
if (!id) {
id = crypto.randomUUID();
localStorage.setItem(key, id);
document.cookie = key + '=' + id + '; path=/; max-age=31536000';
}
window.ours_experiments.init({ visitorId: id });
};
var first = document.getElementsByTagName('script')[0];
first.parentNode.insertBefore(script, first);
})();
</script>Troubleshooting
Experiments not applying
Open the browser console and run:
window.ours_experiments.getAssignments();If you see {}, either no active experiments target the current URL, or the visitor is outside the traffic allocation. Check targeting rules and allocation in the dashboard.
Flicker on page load
The experiment script is loading asynchronously. Move it to a synchronous <script> tag (without async or defer) in <head> before any other scripts.
No experiment data in the dashboard
The CDP pixel snippet is missing or not loading. Make sure the Ours Web SDK pixel snippet is on the page so impression and conversion events reach the server.
Console warning about missing visitorId
The visitor ID was not passed to init(). Make sure you are reading (or creating) the ours_device_id from localStorage/cookies before calling init(). See Resolving the visitor ID.
Can I use my own visitor ID instead of the CDP visitor ID?
No. The visitorId passed to init() must match the Ours CDP identity stored in ours_device_id. Experiment impressions, conversions, and analytics are all tied to this identity. Using a different ID means experiment results in the dashboard will not match your CDP data, and attribution will break.
Next Steps
- JavaScript SDK: Full API reference for
window.ours_experiments - Content A/B Tests: Set up DOM modification experiments
- Redirect Tests: Set up redirect experiments
- Targeting: URL patterns, query parameters, and traffic allocation
How is this guide?