Datafly.js SDKCross-Domain Identity

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.com and then brand-b.com appears 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

  1. User visits Site A — Datafly.js generates anonymous_id: AAA and checks if cross-domain resolution has been performed (localStorage flag)
  2. First visit: redirect to hub — since this is the first visit, Datafly.js redirects to the Identity Hub with the current anonymous_id and return URL
  3. Hub resolves identity — the hub looks up anonymous_id: AAA in 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.
  4. Hub redirects back — the hub redirects back to Site A with an encrypted token (_df_token) in the URL query string
  5. Datafly.js processes token — Datafly.js decodes the token, extracts the canonical anonymous_id, stores it, and cleans the URL
  6. 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_token parameter is removed from the URL via history.replaceState after 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:

  1. A shared subdomain — e.g., id.company.com — that is accessible from all linked domains
  2. DNS configuration — CNAME record pointing to your Datafly cluster’s Identity Hub service
  3. 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

FieldTypeRequiredDescription
hubUrlstringYesFull URL of the Identity Hub resolve endpoint
linkedDomainsstring[]NoList 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_resolved flag is set in localStorage
  • A _df_xd_anon_id value 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 scenarioBehaviour
Hub is unreachableResolution 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 malformedToken is discarded. Resolution is marked complete.
localStorage is unavailableResolution 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.com and brand-b.com)
  • You have separate domains for marketing and e-commerce (e.g., example.com and shop.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 via userId instead)