Cross-Domain Tracking Overview
Cross-domain tracking enables Outbrain to maintain user identity and attribution when users navigate from one domain to another during their conversion journey. Without proper configuration, each domain appears as a separate session, breaking attribution and undercounting conversions.
When Cross-Domain Tracking Is Needed
Common Scenarios
1. Separate checkout domains:
- Main site:
www.example.com - Checkout:
checkout.example.comorsecure.payment-processor.com
2. Multi-brand sites with shared tracking:
- Brand A:
www.brand-a.com - Brand B:
www.brand-b.com - Both brands share Outbrain account and pixel
3. Third-party landing pages:
- Campaign drives to:
landing.thirdparty.com - Conversion happens on:
www.yoursite.com
4. Subdomain navigation:
- Blog:
blog.example.com - Store:
shop.example.com - Account:
account.example.com
5. Content to commerce flows:
- Content hub:
content.example.com - Ecommerce site:
www.example-store.com
How Cross-Domain Tracking Works
- Outbrain appends a unique click ID parameter to the landing page URL when user clicks ad
- This parameter is stored in a first-party cookie on the first domain
- When user navigates to second domain, the parameter is passed via URL or referrer
- Second domain reads the parameter and sets its own cookie with the same click ID
- Conversion on second domain is attributed back to original Outbrain campaign
Implementation Methods
Method 1: URL Parameter Passing (Recommended)
Outbrain automatically appends click tracking parameters to destination URLs. Ensure these parameters are preserved when linking between domains.
Default Outbrain Parameters
ob_click_id: Unique identifier for the clickoutbrain_params: Encoded campaign and content metadata
Step 1: Preserve Parameters in Cross-Domain Links
When linking from Domain A to Domain B, append Outbrain parameters:
// Get current URL parameters
const urlParams = new URLSearchParams(window.location.search);
const obClickId = urlParams.get('ob_click_id');
const obParams = urlParams.get('outbrain_params');
// Build cross-domain link with parameters
function buildCrossDomainLink(targetUrl) {
const url = new URL(targetUrl);
if (obClickId) url.searchParams.set('ob_click_id', obClickId);
if (obParams) url.searchParams.set('outbrain_params', obParams);
return url.toString();
}
// Apply to checkout link
const checkoutLink = buildCrossDomainLink('https://checkout.example.com');
document.getElementById('checkout-btn').href = checkoutLink;
Step 2: Store Parameters in Cookies on Receiving Domain
On the destination domain, read parameters from URL and store in cookies:
// On Domain B, read parameters and store
const urlParams = new URLSearchParams(window.location.search);
const obClickId = urlParams.get('ob_click_id');
if (obClickId) {
// Store in cookie for 30 days (matching default attribution window)
document.cookie = `ob_click_id=${obClickId}; max-age=${30 * 24 * 60 * 60}; path=/; domain=.example.com; secure; samesite=lax`;
}
Step 3: Read Cookie When Firing Conversion
// On conversion page, read cookie and send to Outbrain
function getCookie(name) {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return parts.pop().split(';').shift();
}
const obClickId = getCookie('ob_click_id');
obApi('track', 'Conversion', {
orderValue: 149.99,
orderId: 'ORD-12345',
currency: 'USD',
clickId: obClickId // Include click ID for proper attribution
});
Method 2: GTM Linker Parameter
If using Google Tag Manager on both domains, leverage GTM's cross-domain tracking features.
Step 1: Configure GTM on Both Domains
- Install same GTM container on both domains
- In GTM, create a Variable > 1st Party Cookie named
_ob_click_id - Create trigger for cross-domain links
Step 2: Use GTM's Link Decorator
Create a custom HTML tag that decorates cross-domain links:
<script>
(function() {
// Get Outbrain click ID from URL or cookie
const urlParams = new URLSearchParams(window.location.search);
let obClickId = urlParams.get('ob_click_id');
if (!obClickId) {
obClickId = getCookie('_ob_click_id');
}
if (obClickId) {
// Store in cookie
document.cookie = `_ob_click_id=${obClickId}; max-age=${30 * 24 * 60 * 60}; path=/; domain=.example.com; secure; samesite=lax`;
// Decorate cross-domain links
const links = document.querySelectorAll('a[href*="checkout.example.com"]');
links.forEach(link => {
const url = new URL(link.href);
url.searchParams.set('ob_click_id', obClickId);
link.href = url.toString();
});
}
function getCookie(name) {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return parts.pop().split(';').shift();
}
})();
</script>
Method 3: Subdomain Tracking with Shared Cookies
For subdomains under the same root domain (e.g., shop.example.com and blog.example.com), use shared cookies.
Configure Cookie Domain
Set cookies with the root domain to share across subdomains:
// Set cookie accessible to all subdomains
document.cookie = `ob_click_id=${clickId}; max-age=${30 * 24 * 60 * 60}; path=/; domain=.example.com; secure; samesite=lax`;
Key Points:
- Use
.example.com(with leading dot) to share across subdomains - Do NOT use
.com(too broad, won't work) - Requires HTTPS for
secureflag
Method 4: Server-Side Parameter Handling
For complete control and reliability, handle cross-domain tracking server-side.
Approach
- Capture Outbrain parameters on landing page server-side
- Store in session or database keyed to user session ID
- Pass session ID (not Outbrain parameters) in URLs
- On conversion, retrieve Outbrain parameters from session/database
- Send conversion with original click ID via Conversion API
Example: Express.js
const express = require('express');
const session = require('express-session');
const app = express();
app.use(session({
secret: 'your-secret',
resave: false,
saveUninitialized: true,
cookie: { maxAge: 30 * 24 * 60 * 60 * 1000 } // 30 days
}));
// Landing page: capture Outbrain parameters
app.get('/landing', (req, res) => {
if (req.query.ob_click_id) {
req.session.obClickId = req.query.ob_click_id;
req.session.obParams = req.query.outbrain_params;
}
res.render('landing');
});
// Checkout page on different domain (shared session store)
app.post('/checkout/complete', async (req, res) => {
const obClickId = req.session.obClickId;
if (obClickId) {
// Send conversion to Outbrain with original click ID
await sendOutbrainConversion({
clickId: obClickId,
orderValue: req.body.total,
orderId: req.body.orderId
});
}
res.render('confirmation');
});
Configuration for Specific Scenarios
Scenario 1: Main Site to External Checkout
Setup:
- User clicks Outbrain ad → lands on
www.example.com/product - User clicks checkout → goes to
checkout.stripe.comorpaypal.com - After payment → returns to
www.example.com/thank-you
Solution:
- Store Outbrain click ID in cookie when user lands on product page
- Include return URL with click ID when redirecting to payment processor
- When user returns to thank-you page, read click ID from URL parameter
- Fire Outbrain conversion with stored click ID
// On product page (www.example.com)
const urlParams = new URLSearchParams(window.location.search);
const obClickId = urlParams.get('ob_click_id');
if (obClickId) {
localStorage.setItem('ob_click_id', obClickId);
}
// When redirecting to external checkout
const returnUrl = encodeURIComponent(`https://www.example.com/thank-you?ob_click_id=${localStorage.getItem('ob_click_id')}`);
window.location.href = `https://checkout.stripe.com?return_url=${returnUrl}`;
// On thank-you page (www.example.com/thank-you)
const returnedClickId = new URLSearchParams(window.location.search).get('ob_click_id');
if (returnedClickId) {
obApi('track', 'Conversion', {
orderValue: 99.99,
orderId: 'ORD-12345',
currency: 'USD',
clickId: returnedClickId
});
}
Scenario 2: Multi-Brand Cross-Domain Attribution
Setup:
- Brand A site:
www.brand-a.com - Brand B site:
www.brand-b.com - Shared Outbrain account and pixel
Solution: Use separate Outbrain pixels for each brand, or track which brand user came from:
// On Brand A landing page
const urlParams = new URLSearchParams(window.location.search);
const obClickId = urlParams.get('ob_click_id');
if (obClickId) {
document.cookie = `ob_click_id=${obClickId}; max-age=${30 * 24 * 60 * 60}; path=/; secure; samesite=none`;
document.cookie = `ob_source_brand=brand-a; max-age=${30 * 24 * 60 * 60}; path=/; secure; samesite=none`;
}
// If user navigates to Brand B
// Link from Brand A to Brand B should preserve parameters
const brandBLink = `https://www.brand-b.com/offer?ob_click_id=${obClickId}&source=brand-a`;
Scenario 3: Blog to Store Conversion Funnel
Setup:
- Blog:
blog.example.com(content hub) - Store:
shop.example.com(ecommerce)
Solution: Use shared cookie domain for subdomains:
// On blog.example.com
document.cookie = `ob_click_id=${clickId}; domain=.example.com; path=/; max-age=${30 * 24 * 60 * 60}; secure; samesite=lax`;
// On shop.example.com
// Cookie is automatically accessible, just read and use
const obClickId = getCookie('ob_click_id');
Testing Cross-Domain Tracking
Manual Testing Workflow
- Clear cookies and start fresh
- Click on test Outbrain ad → lands on Domain A with
ob_click_idparameter - Verify parameter appears in URL
- Navigate to Domain B via cross-domain link
- Verify
ob_click_idparameter is preserved in URL or cookie on Domain B - Complete conversion on Domain B
- Check browser network tab for Outbrain conversion request
- Verify conversion appears in Amplify dashboard with correct attribution
Browser DevTools Validation
Check URL Parameters:
// In browser console
console.log(window.location.search);
// Should show: ?ob_click_id=abc123...
Check Cookies:
// In browser console
console.log(document.cookie);
// Should show: ob_click_id=abc123; ...
// Or use Application tab in DevTools > Cookies
Monitor Network Requests:
- Open DevTools > Network tab
- Filter for
outbrainoramplify.outbrain.com - Trigger conversion
- Click on request to inspect parameters
- Verify
clickIdorob_click_idis included in payload
GTM Preview Mode Testing
- Enter GTM Preview mode on Domain A
- Click Outbrain ad or manually add
ob_click_idparameter to URL - Verify GTM variable captures click ID
- Navigate to Domain B (GTM Preview follows you)
- Verify GTM variable on Domain B also has click ID
- Trigger conversion and verify Outbrain tag fires with correct click ID
Common Cross-Domain Issues
Issue: Attribution Lost on Second Domain
Symptom: Conversions on Domain B don't attribute to Outbrain campaigns.
Diagnosis:
- Click ID not preserved when navigating from Domain A to Domain B
- Cookie domain set incorrectly (not accessible on second domain)
- Parameters stripped by redirect or intermediary page
Resolution:
- Ensure cross-domain links include
ob_click_idparameter - Set cookie domain to root domain with leading dot (
.example.com) - Check for URL redirects that might strip query parameters
Issue: Cookie Not Accessible on Subdomain
Symptom: Cookie set on www.example.com not readable on shop.example.com.
Diagnosis:
- Cookie domain set without leading dot:
domain=example.cominstead ofdomain=.example.com
Resolution:
// Correct: accessible on all subdomains
document.cookie = `ob_click_id=${clickId}; domain=.example.com; path=/; secure; samesite=lax`;
Issue: SameSite Cookie Restrictions
Symptom: Cookie not sent when navigating from Domain A to Domain B (different root domains).
Diagnosis:
- Browser blocks third-party cookies
SameSite=StrictorSameSite=Laxprevents cookie from being sent
Resolution:
- Use
SameSite=None; Securefor cross-domain cookies (requires HTTPS) - Pass click ID via URL parameter instead of relying solely on cookies
- Implement server-side session handling
Issue: Multiple Click IDs from Different Visits
Symptom: User has clicked multiple Outbrain ads, which click ID should be used?
Diagnosis:
- New click ID overwrites old one, potentially misattributing conversion
Resolution:
- Use last-click attribution (most recent click ID)
- Store timestamp with click ID and use most recent
- Consider first-click or multi-touch attribution model if needed
Cross-Domain Tracking Checklist
- Identified all domains in conversion funnel
- Outbrain click ID captured from initial landing page URL
- Click ID stored in cookie or session on first domain
- Cross-domain links append click ID parameter to URL
- Receiving domain reads click ID from URL and stores in cookie
- Cookie domain set correctly (root domain with leading dot for subdomains)
- SameSite attribute set appropriately (Lax for subdomains, None for different domains)
- Secure flag enabled (requires HTTPS)
- Conversion tracking includes click ID parameter
- Tested end-to-end with real Outbrain click
- Verified conversion attributes correctly in Amplify dashboard
- Documented cross-domain setup for team reference