Overview
Cross-domain tracking allows FullStory to maintain a continuous session as users navigate between different domains or subdomains. Without proper configuration, each domain transition creates a new session, breaking the user journey and making it difficult to analyze multi-domain flows.
This is essential for businesses that operate across multiple domains, such as:
- Marketing site (
example.com) → App (app.example.com) - E-commerce store (
shop.example.com) → Checkout (checkout.example.com) - Main site (
example.com) → Support portal (support.example.com)
How Cross-Domain Tracking Works
FullStory uses first-party cookies to identify users. By default, cookies are scoped to a single domain. Cross-domain tracking works by:
- Preserving the user identifier as users navigate between domains
- Passing session context via URL parameters or shared cookie domains
- Linking sessions together in FullStory's backend
Same-Domain vs Cross-Domain Scenarios
Same Domain (No Configuration Needed)
These scenarios work automatically without additional setup:
Subdomain to Subdomain (Same Root Domain):
www.example.com→app.example.comshop.example.com→checkout.example.com
FullStory's cookies are set at the root domain level (.example.com), so they're accessible across all subdomains.
Path to Path (Same Hostname):
example.com/pricing→example.com/signupapp.example.com/dashboard→app.example.com/settings
These are the same domain, so sessions continue seamlessly.
Cross-Domain (Requires Configuration)
These scenarios require cross-domain tracking setup:
Different Root Domains:
example.com→exampleapp.ioshop-example.com→checkout-example.com
Different Top-Level Domains (TLDs):
example.com→example.co.ukexample.io→example.net
Configuration Methods
FullStory offers two methods for cross-domain tracking:
Method 1: Shared Cookie Domain (Recommended for Subdomains)
If all your domains share a common root domain, configure FullStory to set cookies at that level.
Example Scenario:
- Main site:
example.com - App:
app.example.com - Shop:
shop.example.com
Configuration:
When initializing FullStory, specify the shared cookie domain:
window['_fs_host'] = 'fullstory.com';
window['_fs_script'] = 'edge.fullstory.com/s/fs.js';
window['_fs_org'] = 'YOUR_ORG_ID';
window['_fs_namespace'] = 'FS';
// Set shared cookie domain
window['_fs_cookie_domain'] = '.example.com'; // Note the leading dot
// Rest of FullStory snippet...
This sets FullStory cookies on .example.com, making them accessible to www.example.com, app.example.com, shop.example.com, etc.
When to Use:
- All domains share a common root (
*.example.com) - You control all subdomains
- Users frequently move between subdomains
Limitations:
- Doesn't work for completely different domains (
example.com→differentdomain.com) - Requires all domains to have FullStory installed
Method 2: URL Parameter Passing (For Different Root Domains)
For completely different domains, FullStory can pass session context via URL parameters.
Example Scenario:
- Marketing site:
example.com - App:
myapp.io
Configuration:
Step 1: Enable URL Parameter Passing
In FullStory dashboard:
- Go to Settings > Cross-Domain Tracking
- Enable "Pass session ID via URL parameters"
- Add trusted domains:
example.com,myapp.io
Step 2: Link Between Domains
When linking from one domain to another, append FullStory's session parameter:
// Automatically append session ID to cross-domain links
document.querySelectorAll('a[href*="myapp.io"]').forEach(link => {
link.addEventListener('click', function(e) {
const sessionURL = FS.getCurrentSessionURL();
if (sessionURL) {
const sessionID = sessionURL.split('/').pop();
const separator = this.href.includes('?') ? '&' : '?';
this.href = this.href + separator + '_fs_session=' + sessionID;
}
});
});
Step 3: Install FullStory on Both Domains
Ensure FullStory is installed with the same Org ID on all domains.
When to Use:
- Domains have completely different root domains
- Users navigate between domains via links
- You need to maintain session continuity across unrelated domains
Limitations:
- Requires JavaScript to append parameters to links
- URL parameter must be preserved during navigation
- Session context can be lost if users manually edit URLs
Implementation Examples
Example 1: E-Commerce with Separate Checkout Domain
Scenario:
- Store:
shop.example.com - Checkout:
checkout.example.com
Solution: Shared Cookie Domain
// On both shop.example.com and checkout.example.com
window['_fs_cookie_domain'] = '.example.com';
Users can now navigate from browsing products to checkout without breaking the session.
Example 2: Marketing Site to SaaS App
Scenario:
- Marketing:
example.com - App:
app.exampleapp.io
Solution: URL Parameter Passing
On example.com:
// Add session ID to "Sign In" and "Get Started" links
document.querySelectorAll('a[href*="app.exampleapp.io"]').forEach(link => {
link.addEventListener('click', function(e) {
const sessionURL = FS.getCurrentSessionURL();
if (sessionURL) {
const sessionID = sessionURL.split('/').pop();
const separator = this.href.includes('?') ? '&' : '?';
this.href = this.href + separator + '_fs_session=' + sessionID;
}
});
});
On app.exampleapp.io:
Ensure FullStory is installed with the same Org ID. FullStory will automatically detect the _fs_session parameter and continue the session.
Example 3: Multi-Region Sites
Scenario:
- US site:
example.com - UK site:
example.co.uk - EU site:
example.eu
Solution: URL Parameter Passing + Conditional Cookie Domain
Configure per-region:
// Dynamically set cookie domain based on hostname
const hostname = window.location.hostname;
if (hostname.endsWith('.com')) {
window['_fs_cookie_domain'] = '.example.com';
} else if (hostname.endsWith('.co.uk')) {
window['_fs_cookie_domain'] = '.example.co.uk';
} else if (hostname.endsWith('.eu')) {
window['_fs_cookie_domain'] = '.example.eu';
}
For cross-region navigation:
Use URL parameter passing when users switch between .com → .co.uk.
Testing Cross-Domain Tracking
Verification Steps
Start a session on Domain A:
- Visit
example.com - Open DevTools Console
- Run:
FS.getCurrentSessionURL() - Copy the session URL (e.g.,
https://app.fullstory.com/ui/o-XYZ-na1/session/12345)
- Visit
Navigate to Domain B:
- Click a link to
app.example.com(or different domain) - Open DevTools Console on the new domain
- Run:
FS.getCurrentSessionURL()
- Click a link to
Compare session IDs:
- If session IDs match → Cross-domain tracking is working
- If session IDs differ → Cross-domain tracking failed
Common Issues
Session breaks despite shared cookie domain:
Possible causes:
- Cookie domain configured incorrectly (missing leading dot)
- Different FullStory Org IDs on each domain
- FullStory not installed on one of the domains
Solution:
// Correct
window['_fs_cookie_domain'] = '.example.com'; // Leading dot
// Incorrect
window['_fs_cookie_domain'] = 'example.com'; // No leading dot
URL parameters not working:
Possible causes:
- Parameters stripped by redirects or server-side routing
- JavaScript not appending parameters correctly
- Session parameter name incorrect
Solution:
// Verify parameter is appended
console.log(link.href); // Should include ?_fs_session=12345
Advanced Configuration
Excluding Specific Subdomains
If you have subdomains that shouldn't share sessions (e.g., admin panels), use different Org IDs:
// On www.example.com and app.example.com
window['_fs_org'] = 'o-PROD-na1';
window['_fs_cookie_domain'] = '.example.com';
// On admin.example.com (separate Org ID)
window['_fs_org'] = 'o-ADMIN-na1';
window['_fs_cookie_domain'] = 'admin.example.com'; // No leading dot
Tracking Across iframes
For tracking users within iframes (same domain):
// Parent page
window['_fs_cookie_domain'] = '.example.com';
// Iframe (on iframe.example.com)
window['_fs_cookie_domain'] = '.example.com';
FullStory will automatically link activity in the iframe to the parent session.
Note: Cross-origin iframes (different domains) are not recorded by FullStory due to browser security restrictions.
Dynamic Link Parameter Injection
For sites with dynamically generated links:
// Automatically append session ID to all external cross-domain links
function injectFullStorySession() {
const sessionURL = FS.getCurrentSessionURL();
if (!sessionURL) return;
const sessionID = sessionURL.split('/').pop();
const targetDomains = ['app.exampleapp.io', 'checkout.example.net'];
document.querySelectorAll('a').forEach(link => {
const href = link.getAttribute('href');
if (!href) return;
targetDomains.forEach(domain => {
if (href.includes(domain) && !href.includes('_fs_session=')) {
const separator = href.includes('?') ? '&' : '?';
link.href = href + separator + '_fs_session=' + sessionID;
}
});
});
}
// Run on page load and after dynamic content is added
window.addEventListener('load', injectFullStorySession);
// For SPAs, run after route changes
// Example for React Router:
// useEffect(() => { injectFullStorySession(); }, [location]);
Privacy Considerations
Cookie Consent & Cross-Domain Tracking
If your site requires cookie consent (GDPR, CCPA):
// Only set shared cookie domain after consent
function onConsentGranted() {
window['_fs_cookie_domain'] = '.example.com';
FS.restart(); // Restart recording with new cookie domain
}
// On consent denial
function onConsentDenied() {
FS.shutdown();
}
Data Sharing Between Domains
Ensure your privacy policy discloses cross-domain tracking:
"We use FullStory to track user behavior across our website and app (example.com and app.example.com). FullStory uses cookies to maintain session continuity as you navigate between these domains."
Best Practices
Use Shared Cookie Domain for Subdomains
If all your domains are subdomains of a common root, always use shared cookie domain method. It's simpler and more reliable than URL parameters.
Document Your Domain Structure
Maintain documentation of:
- All domains using FullStory
- Which domains share sessions
- Which Org ID each domain uses
- Cross-domain link mapping
Test Cross-Domain Flows Regularly
Create test scenarios:
- Navigate from marketing site to app
- Complete checkout flow across domains
- Verify session continuity in FullStory dashboard
Monitor Session Continuity
Use FullStory's Omnisearch to verify cross-domain sessions:
Search: user.email = "test@example.com"
Filter by: Multiple page views across different domains
If sessions are splitting, investigate cross-domain configuration.
Troubleshooting
Common Cross-Domain Issues
| Issue | Symptoms | Possible Causes | Solutions |
|---|---|---|---|
| Sessions splitting across domains | New session starts when navigating to different domain | - Different Org IDs on each domain - Cookie domain not configured - URL parameter not passed - Browser blocking third-party cookies |
- Use same Org ID on all domains - Set _fs_cookie_domain to shared root- Append _fs_session parameter to links- Use first-party cookies only |
| Cookie domain not working | Shared cookie domain set but sessions still split | - Missing leading dot in cookie domain - Domains don't share root - Browser security settings - Incorrect cookie domain value |
- Add leading dot: ._fs_cookie_domain = '.example.com'- Verify domains share root (e.g., *.example.com)- Test in incognito mode - Check cookie domain in DevTools |
| URL parameters stripped | _fs_session parameter removed during navigation |
- Server-side redirect removing params - Client-side router stripping params - Form POST losing parameters |
- Preserve URL parameters in redirects - Manually re-append parameters after route change - Use hidden form fields for POST requests |
| Different root domains not linking | Sessions don't connect across .com and .co.uk |
- Cannot share cookies across TLDs - URL parameter not passed - FullStory not installed on both |
- Use URL parameter method - Append _fs_session to cross-domain links- Install FullStory with same Org ID on both |
| User identification not persisting | User identified on one domain but not another | - FS.identify() not called on second domain- Different user IDs used - Identify called after navigation |
- Call FS.identify() on all domains- Use consistent user ID format - Identify immediately on page load |
| Session URL parameter not recognized | Parameter in URL but session still splits | - Parameter name misspelled - FullStory version doesn't support feature - Parameter value corrupted |
- Use exact name: _fs_session- Update to latest FullStory version - Validate parameter value is session ID |
| Cross-origin iframe issues | Parent and iframe sessions not linking | - Cross-origin security restrictions - FullStory not on both pages - Different Org IDs |
- Same-origin iframes work automatically - Cross-origin iframes cannot share sessions (browser limitation) - Install FullStory with same Org ID |
| Cookie consent blocking tracking | GDPR consent preventing cross-domain cookies | - Consent not granted before navigation - Cookie banner blocking FullStory - Consent state not shared across domains |
- Get consent before cross-domain navigation - Share consent state via URL or backend - Initialize FullStory after consent |
| Performance degradation | Page load slow after adding cross-domain setup | - Synchronous link modification - Too many links being processed - Heavy DOM manipulation |
- Use async link processing - Target specific links only - Optimize selector performance |
| Testing shows success but production fails | Works in staging but not production | - Different domain configuration - Production firewall/CDN interference - Environment-specific cookie settings |
- Verify production domain config matches staging - Check CDN/firewall settings - Test in production-like environment |
Debugging Cross-Domain Tracking
Step 1: Verify Session ID on First Domain
// On domain A (e.g., example.com)
const sessionURL = FS.getCurrentSessionURL();
console.log('Session URL:', sessionURL);
// Extract session ID
const sessionID = sessionURL ? sessionURL.split('/').pop() : null;
console.log('Session ID:', sessionID);
Step 2: Check Link Parameter Injection
// Verify links have session parameter
document.querySelectorAll('a[href*="app.example.io"]').forEach(link => {
console.log('Link href:', link.href);
// Should include ?_fs_session=SESSION_ID or &_fs_session=SESSION_ID
});
Step 3: Verify Session on Second Domain
// On domain B (e.g., app.example.io)
// Check for session parameter in URL
const urlParams = new URLSearchParams(window.location.search);
const passedSessionID = urlParams.get('_fs_session');
console.log('Passed session ID:', passedSessionID);
// Get current session
const currentSessionURL = FS.getCurrentSessionURL();
const currentSessionID = currentSessionURL ? currentSessionURL.split('/').pop() : null;
console.log('Current session ID:', currentSessionID);
// Compare - should match
if (passedSessionID === currentSessionID) {
console.log('Cross-domain tracking working!');
} else {
console.error('Session IDs do not match');
}
Step 4: Check Cookie Domain
// View FullStory cookies
document.cookie.split(';').forEach(cookie => {
if (cookie.includes('fs_')) {
console.log('FullStory cookie:', cookie.trim());
}
});
// Check cookie domain in DevTools:
// 1. Open DevTools > Application tab
// 2. Go to Cookies section
// 3. Look for cookies starting with `fs_`
// 4. Check "Domain" column - should show `.example.com` (with leading dot)
Validation Steps
Test Subdomain Tracking:
- Set cookie domain to
.example.com - Visit
www.example.com - Get session URL
- Navigate to
app.example.com - Get session URL again
- Verify: Session IDs match
Test Cross-Domain (Different Roots):
- Visit
example.com - Get session URL and ID
- Click link to
exampleapp.io(with_fs_sessionparameter) - On
exampleapp.io, check URL for_fs_sessionparameter - Get current session URL
- Verify: Session IDs match
Test User Identification:
- Login on domain A
- FS.identify() is called
- Navigate to domain B
- Check if user still identified
- Verify: User properties persist
Cookie Configuration Validation
Check cookie domain setting:
// Should be set before FullStory loads
console.log('Cookie domain:', window._fs_cookie_domain);
// For subdomains of example.com, should be:
// ".example.com" (with leading dot)
Verify cookie is set correctly:
# In browser DevTools Console
document.cookie.split(';').forEach(c => console.log(c.trim()));
# Look for:
# fs_uid=... (user identifier)
# Domain should show .example.com
Common Configuration Mistakes
Missing leading dot:
// Wrong
window['_fs_cookie_domain'] = 'example.com';
// Correct
window['_fs_cookie_domain'] = '.example.com';
Incorrect session parameter name:
// Wrong
const url = `${targetUrl}?fs_session=${sessionID}`;
// Correct
const url = `${targetUrl}?_fs_session=${sessionID}`;
// Note the underscore prefix: _fs_session
Not preserving parameters during navigation:
// Wrong - Parameter gets stripped
window.location.href = '/new-page'; // Loses _fs_session
// Correct - Preserve parameter
const sessionParam = new URLSearchParams(window.location.search).get('_fs_session');
if (sessionParam) {
window.location.href = `/new-page?_fs_session=${sessionParam}`;
}
Using different Org IDs:
// Wrong - Different Org IDs won't link sessions
// On example.com
window['_fs_org'] = 'o-ABC-na1';
// On app.example.com
window['_fs_org'] = 'o-XYZ-na1'; // Different!
// Correct - Same Org ID everywhere
window['_fs_org'] = 'o-ABC-na1';
Advanced Debugging
Monitor cookie changes:
// Track cookie changes
let lastCookies = document.cookie;
setInterval(() => {
if (document.cookie !== lastCookies) {
console.log('Cookies changed!');
console.log('Old:', lastCookies);
console.log('New:', document.cookie);
lastCookies = document.cookie;
}
}, 1000);
Log cross-domain navigation:
// Add to links for debugging
document.querySelectorAll('a[href*="different-domain.com"]').forEach(link => {
link.addEventListener('click', function(e) {
const sessionURL = FS.getCurrentSessionURL();
const sessionID = sessionURL ? sessionURL.split('/').pop() : null;
console.log('[Cross-Domain Nav]', {
from: window.location.href,
to: this.href,
sessionID: sessionID,
hasParameter: this.href.includes('_fs_session')
});
});
});
Getting Help
If cross-domain tracking still not working:
- Verify basic FullStory setup works on each domain individually
- Check FullStory Status: status.fullstory.com
- Review Help Center: help.fullstory.com
- Contact Support: Include:
- Both domain names
- Cookie domain setting
- Session URLs from both domains
- Screenshots of cookies in DevTools
- Network tab showing FullStory requests
Next Steps:
- Data Layer Setup - Configure GTM data layer
- Event Tracking - Track custom events
- Install or Embed Tag - Deploy FullStory
Additional Resources: