feat: identify() + cross-subdomain anonymous ID cookie (v0.3.0)#3
Conversation
release.yml:
- Use git ls-remote instead of git rev-parse for tag check so
remote tags are detected reliably (not just local refs)
- Pin release target to merge_commit_sha instead of moving main
branch ref to avoid race conditions
src/index.ts:
- parseUTM: use URL base parameter so relative URLs and query-only
inputs ('?utm_source=google', '/page?utm_medium=cpc') resolve
correctly instead of throwing
- persistUTM/getPersistedUTM: validate JSON.parse output is a plain
object before spreading, preventing corrupt sessionStorage from
injecting unexpected metadata fields
- Constructor: always read back from getPersistedUTM() after persist
so in-memory UTM state includes previously persisted keys merged
with fresh ones, not just the fresh subset
The pull_request.closed event checks out the PR merge ref by default, which can yield an empty version read. Explicitly checkout main with fetch-depth: 0 so package.json and git tags are both available.
- Add identify() to stitch anonymous_id to a known contact via the identify relay API on the loyalty/operator backend - Generate and persist anonymous_id in localStorage + cross-subdomain cookie (.bagdock.com, 400-day TTL, SameSite=lax) - Include anonymous_id in every tracked event payload - Export IdentifyParams type and anonymousId getter - Cookie priority: cookie > localStorage > generate fresh
- Bump version 0.2.0 → 0.3.0 - Add "How to identify visitors" section with code examples - Document IdentifyParams type and anonymousId getter - Add identify() and anonymousId to Methods table - Update Data privacy section to describe the anonymous ID cookie
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (4)
WalkthroughThe pull request implements visitor identification functionality for the Bagdock Analytics SDK. It introduces an Changes
Sequence DiagramsequenceDiagram
actor App as App
participant SDK as Bagdock Analytics SDK
participant Storage as Browser Storage
participant API as Bagdock API
rect rgba(100, 150, 200, 0.5)
Note over App,API: Anonymous ID Generation & Persistence
SDK->>Storage: Check localStorage/cookie for anonymousId
alt ID exists
Storage-->>SDK: Return existing anonymousId
else ID not found
SDK->>SDK: Generate new anonymousId
SDK->>Storage: Save to localStorage + .bagdock.com cookie
end
SDK->>App: anonymousId ready (via getter)
end
rect rgba(150, 100, 200, 0.5)
Note over App,API: Visitor Identification
App->>SDK: identify({ contactId, operatorId?, traits? })
SDK->>SDK: Build identify payload with anonymous_id, utm, landing_page, referrer
SDK->>API: POST /api/identify (with Authorization header)
API-->>SDK: { stitched } response
SDK->>App: Promise resolves (silently catches errors)
end
rect rgba(100, 200, 150, 0.5)
Note over App,API: Event Tracking with Anonymous ID
App->>SDK: track(event)
SDK->>SDK: Build event payload with anonymous_id
SDK->>API: POST event with anonymous_id included
API-->>SDK: Acknowledgement
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related PRs
Poem
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
| function setCrossDomainCookie(name: string, value: string): void { | ||
| if (typeof document === 'undefined') return | ||
| const hostname = typeof window !== 'undefined' ? window.location.hostname : '' | ||
| const domain = hostname.endsWith('bagdock.com') ? '.bagdock.com' : undefined |
Summary
identify(params)— stitch the current anonymous ID to a known contact by POSTing to the Bagdock identify relay (/api/identify). Upsertscontact_anonymous_idson the operator database and optionally backfills contact traits + first-touch UTM attribution.bagdock_anon_idon first visit, persisted in bothlocalStorageand a.bagdock.comcookie (400-day TTL,SameSite=lax). The same ID follows visitors across marketing site, checkout, and customer app so pre-identify events are attributed correctly.anonymous_idin every event payload — alltrack()calls now include the anonymous ID, enabling server-side correlation of events to contacts even beforeidentify()is called.anonymousIdgetter — read the current anonymous ID from the SDK instance.0.2.0→0.3.0.Test plan
new BagdockAnalytics({ apiKey, debug: true })logs anonymous ID on initanalytics.anonymousIdreturns a UUID stringanalytics.identify({ contactId: 'ct_x' })POSTs to/api/identifywith anonymous_id, contact_id, UTM, landing_pagebagdock_anon_idset on.bagdock.comwith ~400-day max-agetrack()payloads includeanonymous_idfieldnpm run buildproduces clean dist with new exportsSummary by CodeRabbit
New Features
identify()method for stitching user sessions.Documentation
Chores