Skip to main content
DATALYR automatically identifies visitors to build complete customer journeys, even across multiple sessions and devices.

How Visitor Identification Works

Every visitor gets a unique anonymous ID that persists across sessions. When users log in or provide their email, DATALYR links their anonymous ID to their user ID for cross-device tracking.

Anonymous ID

What it is: A unique identifier automatically generated for every visitor (anon_abc123...). How it’s stored:
  • Primary: Root domain cookie (__dl_visitor_id)
  • Backup: localStorage (dl_anonymous_id)
Persistence:
  • Lasts 1 year by default
  • Works across subdomains (e.g., www.example.com and app.example.com)
  • Survives browser restarts
  • Does NOT survive browser data clearing
Generation:
// Automatically generated on first visit
anon_f47ac10b-58cc-4372-a567-0e02b2c3d479

User ID

What it is: Your internal identifier for logged-in users (user_123, email address, database ID, etc.). How it’s set:
// Web
datalyr.identify('user_123', {
  email: '[email protected]',
  name: 'John Doe',
  plan: 'pro'
});

// iOS
await DatalyrSDK.shared.identify("user_123", properties: [
    "email": "[email protected]"
])

// React Native
await Datalyr.identify('user_123', {
  email: '[email protected]'
});
Persistence:
  • Stored in localStorage (dl_user_id)
  • Survives page reloads and browser restarts
  • Cleared on logout (call datalyr.reset())

Distinct ID

What it is: The primary identifier DATALYR uses for each visitor. Logic:
Distinct ID = User ID (if logged in) || Anonymous ID
Example Flow:
Visit 1: anonymous_id = anon_abc123
         distinct_id = anon_abc123

User logs in:
         anonymous_id = anon_abc123 (unchanged)
         user_id = user_456
         distinct_id = user_456

Visit 2 (same browser):
         anonymous_id = anon_abc123
         user_id = user_456
         distinct_id = user_456

Cross-Subdomain Tracking

DATALYR automatically tracks visitors across subdomains using root domain cookies.

How It Works

When a visitor first arrives at www.example.com:
  1. DATALYR generates anon_abc123
  2. Sets cookie on root domain (.example.com)
  3. Cookie is accessible on all subdomains
When the same visitor goes to app.example.com:
  1. DATALYR reads cookie from root domain
  2. Uses same anon_abc123 ID
  3. Journey continues seamlessly

Supported Domains

Standard TLDs:
  • .com, .net, .org → Cookie set on .example.com
Country-Specific TLDs:
  • .co.uk, .com.au, .co.nz → Cookie set on .example.co.uk
Localhost:
  • localhost → Cookie set on localhost
IP Addresses:
  • 192.168.1.1 → Cookie set on exact IP

Cross-Device Tracking

Link visitors across devices using user identification.

Example Journey

Device 1 (Mobile):
Day 1, 10:00 AM - Mobile phone
- Clicks Meta ad (fbclid captured)
- anonymous_id: anon_mobile_123
- Browses products
- Does NOT purchase
Device 2 (Desktop):
Day 1, 8:00 PM - Desktop computer
- Types URL directly (direct traffic)
- anonymous_id: anon_desktop_456
- Logs in as user_789
- Completes purchase
Without Identify:
  • Purchase attributed to “direct” (wrong!)
  • Ad spend wasted
With Identify:
// User logs in on mobile
datalyr.identify('user_789');
// anonymous_id: anon_mobile_123 → user_id: user_789

// User logs in on desktop
datalyr.identify('user_789');
// anonymous_id: anon_desktop_456 → user_id: user_789

// Purchase attributed correctly to Meta ad!
DATALYR links both devices to user_789 and attributes the purchase to the original Facebook ad.

Session Tracking

Sessions track continuous user activity with 30-minute timeout.

Session ID

Format:
sess_1727634645123_a1b2c3d4
Components:
  • sess_: Prefix
  • 1727634645123: Timestamp (milliseconds)
  • a1b2c3d4: Random identifier
Storage:
  • Stored in localStorage (dl_session_data)
  • Includes start time, last activity, page count, event count

Session Lifecycle

New Session Starts When:
  • First visit to site
  • 30 minutes of inactivity
  • Browser is closed and reopened (after timeout)
Session Continues When:
  • User navigates between pages
  • User is active (clicks, scrolls, etc.)
  • Time since last activity is less than 30 minutes
Session Ends When:
  • 30 minutes of inactivity
  • User closes browser (eventually)
  • datalyr.reset() is called

Session Data

Each session stores:
{
  "id": "sess_1727634645123_a1b2c3d4",
  "startTime": 1727634645123,
  "lastActivity": 1727638245123,
  "pageCount": 5,
  "eventCount": 23
}

Identity Resolution

DATALYR automatically links anonymous IDs to user IDs when you call identify().

How It Works

  1. Pre-Login:
    anonymous_id: anon_abc123
    user_id: null
    distinct_id: anon_abc123
    
  2. User Identifies (Login/Signup):
    datalyr.identify('user_456');
    
  3. Post-Login:
    anonymous_id: anon_abc123 (unchanged)
    user_id: user_456
    distinct_id: user_456
    
  4. Identity Link Event Sent:
    {
      "event_name": "$identify",
      "anonymous_id": "anon_abc123",
      "user_id": "user_456",
      "previous_id": null,
      "identified_at": "2025-09-29T10:30:45.123Z"
    }
    
  5. All Past Events Linked:
    • DATALYR retroactively links all anon_abc123 events to user_456
    • Complete journey from anonymous → identified
    • Attribution preserved across identification
Name: __dl_visitor_id Value: Anonymous ID (anon_...) Attributes:
  • Domain: Root domain (e.g., .example.com)
  • Path: /
  • Max-Age: 31536000 (1 year)
  • SameSite: Lax
  • Secure: Yes (on HTTPS sites)
Example:
__dl_visitor_id=anon_f47ac10b-58cc-4372-a567-0e02b2c3d479; domain=.example.com; path=/; max-age=31536000; SameSite=Lax; Secure

localStorage Backup

DATALYR also stores IDs in localStorage as a backup: Keys:
  • dl_anonymous_id: Anonymous ID
  • dl_user_id: User ID (after identify)
  • dl_session_data: Current session info
Why Both Cookie and localStorage?
  • Cookie: Works across subdomains
  • localStorage: Survives when cookies are blocked or deleted
  • Fallback strategy ensures tracking continues

Privacy and Compliance

Opt-Out

Users can opt out of tracking:
// User opts out
datalyr.optOut();
This sets a cookie:
__dl_opt_out=true
All tracking stops. To opt back in:
datalyr.optIn();

Do Not Track

DATALYR respects browser Do Not Track (DNT) settings by default: Respected Signals:
  • navigator.doNotTrack === '1'
  • navigator.globalPrivacyControl === true
  • window.globalPrivacyControl === true
To disable DNT respect:
datalyr.init({
  workspaceId: 'ws_123',
  respectDoNotTrack: false // Don't respect DNT
});

GDPR Compliance

Clear user data on request:
// Remove user ID (keeps anonymous_id for analytics)
datalyr.reset();

// OR fully opt out
datalyr.optOut();

Troubleshooting

Visitor ID changes on every page load? Check that:
  • Cookies are enabled in browser
  • Third-party cookie blockers are disabled
  • You’re not in incognito/private mode
  • Cookie domain is set correctly
Cross-subdomain tracking not working? Verify:
  • Both subdomains are on same root domain
  • Cookie is set on root domain (check with DevTools)
  • No cookie blockers interfering
User ID not persisting? Check:
  • identify() was called with a non-empty userId
  • localStorage is available (not disabled)
  • reset() wasn’t called unintentionally
Anonymous ID lost after browser restart? This means:
  • Cookies were cleared by user
  • Cookie didn’t save properly (check domain)
  • localStorage also cleared

Next Steps

Need Help?

Questions about visitor identification? Check our troubleshooting guide or contact support.