Cross-Domain Identity
When your business operates multiple domains (e.g., www.example.com and shop.example.com, or brand-a.com and brand-b.com), each domain gets its own _dfid cookie and anonymous ID. The cross-domain identity feature links these separate identities into a single user profile through Datafly’s Identity Hub.
The problem
Browsers enforce strict cookie isolation between domains. A cookie set on example.com cannot be read by other-brand.com. This means:
- A user who visits
brand-a.comand thenbrand-b.comappears as two separate anonymous users - Conversion attribution breaks when the ad click lands on one domain and the purchase happens on another
- User journeys spanning multiple domains cannot be stitched together
The solution
Datafly’s Identity Hub acts as a shared intermediary at a neutral subdomain (e.g., id.company.com). When cross-domain is enabled, Datafly.js redirects first-time visitors through the hub, which resolves their identity across domains using an encrypted token.
Site A (brand-a.com) Identity Hub Site B (brand-b.com)
┌─────────────────┐ (id.company.com) ┌─────────────────┐
│ │ │ │
│ User visits │──── redirect ────>┌──────────┐ │ │
│ brand-a.com │ │ Hub │ │ │
│ │ │ looks up│ │ │
│ anon_id: AAA │ │ or │ │ │
│ │<── redirect ──────│ creates │ │ │
│ anon_id: AAA │ + encrypted │ canonical │ │
│ (confirmed) │ token │ identity│ │ │
│ │ └──────────┘ │ │
└─────────────────┘ │ │
│ User visits │
│ brand-b.com │
│ │
│ anon_id: BBB │
│──── redirect ──>│
│ │
│ Hub returns │
│ anon_id: AAA │
│ (same user!) │
└─────────────────┘How it works
Step by step
- User visits Site A — Datafly.js generates
anonymous_id: AAAand checks if cross-domain resolution has been performed (localStorage flag) - First visit: redirect to hub — since this is the first visit, Datafly.js redirects to the Identity Hub with the current
anonymous_idand return URL - Hub resolves identity — the hub looks up
anonymous_id: AAAin its database. If this is the first time, it stores it as the canonical ID. If a previous domain already registered, it returns the existing canonical ID. - Hub redirects back — the hub redirects back to Site A with an encrypted token (
_df_token) in the URL query string - Datafly.js processes token — Datafly.js decodes the token, extracts the canonical
anonymous_id, stores it, and cleans the URL - Resolution is cached — the resolved ID is stored in localStorage and the hub redirect will not happen again for this browser
When the same user later visits Site B, the same flow occurs. The hub recognises the user (via its own first-party cookie on id.company.com) and returns the same canonical anonymous_id: AAA, linking both domains.
Token security
The token returned from the Identity Hub is encrypted with AES-256-GCM:
- Encryption: AES-256-GCM with a shared key between the hub and Datafly.js backend
- TTL: 60 seconds — tokens expire quickly to prevent replay attacks
- Payload:
{ anonymousId: string, exp: number }(canonical anonymous ID and expiration timestamp) - URL cleanup: the
_df_tokenparameter is removed from the URL viahistory.replaceStateafter processing, so it does not appear in analytics or bookmarks
The token is encrypted server-side and decrypted client-side for the initial implementation. In production, the token should be validated server-side by the Ingestion Gateway on the first event to prevent token tampering. The 60-second TTL limits the window for any potential misuse.
Configuration
Source configuration
Enable cross-domain identity in your source configuration:
{
"cross_domain": {
"enabled": true,
"hub_url": "https://id.company.com/resolve",
"linked_domains": ["brand-a.com", "brand-b.com", "shop.brand-a.com"]
}
}Datafly.js init
When using the npm package, pass the cross-domain configuration to init():
import datafly from '@datafly/collector';
datafly.init({
pipelineKey: 'dk_live_abc123',
endpoint: 'https://data.brand-a.com',
crossDomain: {
hubUrl: 'https://id.company.com/resolve',
linkedDomains: ['brand-a.com', 'brand-b.com'],
},
});When using the script tag method, cross-domain configuration is loaded from the source configuration on the server. No additional client-side configuration is needed.
Identity Hub setup
The Identity Hub requires:
- A shared subdomain — e.g.,
id.company.com— that is accessible from all linked domains - DNS configuration — CNAME record pointing to your Datafly cluster’s Identity Hub service
- SSL certificate — valid TLS certificate for the hub subdomain (automatically provisioned by the cluster)
The hub sets its own first-party cookie on id.company.com to recognise returning users across domains.
Configuration reference
| Field | Type | Required | Description |
|---|---|---|---|
hubUrl | string | Yes | Full URL of the Identity Hub resolve endpoint |
linkedDomains | string[] | No | List of domains to link (informational, sent to hub) |
Redirect behaviour
The redirect to the Identity Hub happens only once per browser. After the first resolution:
- A
_df_xd_resolvedflag is set in localStorage - A
_df_xd_anon_idvalue stores the resolved canonical ID - Subsequent page loads skip the redirect entirely
The redirect adds a small delay (typically 100—300ms) to the very first page load on each domain. This happens only once per browser and is not noticeable on subsequent visits. The redirect uses a 302 (temporary) redirect, so it is not cached by browsers or search engines.
Failure handling
Datafly.js is designed to degrade gracefully if cross-domain resolution fails:
| Failure scenario | Behaviour |
|---|---|
| Hub is unreachable | Resolution is marked complete to prevent redirect loops. User gets a per-domain anonymous ID. |
| Token is expired (>60s) | Token is discarded. User gets a per-domain anonymous ID. |
| Token is malformed | Token is discarded. Resolution is marked complete. |
| localStorage is unavailable | Resolution runs on every page load but does not cause loops (hub cookie prevents re-resolution). |
In all failure cases, tracking continues normally with a domain-specific anonymous ID. No events are lost.
When to use cross-domain identity
Cross-domain identity is appropriate when:
- You operate multiple top-level domains that share users (e.g.,
brand-a.comandbrand-b.com) - You have separate domains for marketing and e-commerce (e.g.,
example.comandshop.example.com) - Ad clicks land on one domain and conversions happen on another
Cross-domain identity is not needed when:
- All your sites are on subdomains of the same root domain (cookies can be shared via
domain=.example.com) - You only operate a single domain
- Users authenticate on each domain (use
identify()to link identities viauserIdinstead)