Headless Personalization
Code-driven personalization with Ours Privacy. Use window.ours_experiments.getVisitorContext() to access geo, UTM, device, and visitor status, and render targeted content in your own application code.
Headless Personalization
Headless personalization is the code-driven personalization pattern for Ours Privacy. Your application reads visitor signals — geo, UTM, device, and visitor status — from window.ours_experiments.getVisitorContext() and renders targeted content directly in your own JavaScript.
Use this when you want to make rendering decisions from visitor signals. For dashboard-managed always-on rules, see Content Personalization (coming soon). For experiment assignment APIs (which variant the visitor was assigned to), see the JavaScript SDK.
Quick Start
const ctx = window.ours_experiments.getVisitorContext();
// Geo-targeted content
if (ctx.geo.country_region === 'TX') {
showTexasComplianceBanner();
}
// Campaign-specific messaging
if (ctx.utm.source === 'meta' && ctx.visitor_status === 'new') {
showFacebookWelcomeOffer();
}
// Device-specific layout
if (ctx.device.type === 'mobile') {
showMobileOptimizedHero();
}Browser Signals
Signals available immediately on page load.
UTM Parameters
ctx.utm;
// {
// source: 'meta',
// medium: 'paid',
// campaign: 'spring-2026',
// content: 'hero-cta',
// term: 'privacy software'
// }All values are string | null. Parsed from window.location.search on each page load.
Initial UTM Parameters
ctx.initial_utm;
// {
// source: 'meta',
// medium: 'paid',
// campaign: 'spring-2026',
// content: null,
// term: null
// }The visitor's UTM values from their first tracked arrival for the current experiment cookie, persisted in the experiment cookie. Set once on the first visit that carries any UTM parameter for that tracked visitor, then reused on later pageviews for the same visitor ID.
- Returns
nullif the visitor has never arrived via a URL with UTM parameters. - Same shape as
ctx.utmwhen present. - Useful for targeting or analytics based on the visitor's original acquisition channel, regardless of their current page.
// Show content based on original acquisition channel
if (ctx.initial_utm?.source === 'meta' && ctx.utm.source === null) {
showReturningFacebookVisitorOffer();
}Query Parameters
ctx.query_params;
// { utm_source: 'meta', ref: 'partner-123', promo: 'SAVE20' }All current URL query parameters as a flat key-value object.
Visitor Status
ctx.visitor_status; // 'new' | 'returning'Based on whether the current visitor ID has already been seen by the experiment runtime for this browser's experiment cookie.
Referrer
ctx.referrer; // 'https://google.com/search?q=...' | nullDevice & Browser
ctx.device;
// {
// type: 'mobile', // 'desktop' | 'mobile' | 'tablet'
// os: 'iOS',
// browser: 'Safari',
// screen_width: 390,
// screen_height: 844,
// language: 'en-US'
// }Time
ctx.time;
// {
// day_of_week: 2, // 0 (Sunday) – 6 (Saturday)
// hour: 14, // 0-23, visitor's local time
// timezone: 'America/Chicago'
// }Geo and Device Signals
Geographic and device signals are resolved at the edge and available alongside the browser signals above.
Geolocation
ctx.geo;
// {
// country: 'US',
// country_region: 'TX',
// city: 'Austin',
// time_zone: 'America/Chicago'
// }Device Type
ctx.geo.is_mobile_viewer; // 'true' | 'false'
ctx.geo.is_desktop_viewer; // 'true' | 'false'
ctx.geo.is_tablet_viewer; // 'true' | 'false'Edge-resolved device flags that complement the client-side ctx.device object.
Event: visitor:ready
Subscribe to the visitor context becoming available after window.ours_experiments.init(...) runs:
window.ours_experiments.on('visitor:ready', (ctx) => {
// ctx contains the current visitor context
if (ctx.geo.country_region === 'CA') {
showCaliforniaDisclosure();
}
});If you are attaching listeners after the runtime has already loaded, call window.ours_experiments.getVisitorContext() directly.
Use Cases
Geographic compliance messaging: Show state-specific disclaimers or pricing based on ctx.geo.country_region.
Campaign-matched landing pages: Adjust hero copy to match the ad the visitor clicked, using ctx.utm.source and ctx.utm.campaign.
Returning visitor recognition: Show a loyalty message or skip the intro for returning visitors using ctx.visitor_status.
Analytics enrichment: Push visitor geo, UTM, and device data into your analytics tool or GTM dataLayer.
Conditional rendering: Show or hide page sections based on any combination of visitor signals — device type, location, behavior history.
Next Steps
- Content Personalization: Always-on audience targeting rules configured in the dashboard (coming soon)
- Headless Experiments: Run an A/B test where your application code renders the variant
- JavaScript SDK: Experiment assignments and event subscriptions
- Installation: Set up the experiment runtime on your site
How is this guide?

