New:Microsoft Teams Notifications Are Now Available in Socket.Learn more →
Get Started

@crelora/mark

Package Overview
Dependencies
Maintainers
1
Versions
26
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@crelora/mark

Mark is Crelora's lightweight attribution SDK for capturing user journeys, conversions, and consent across browsers and server-side runtimes. The npm package includes both browser and Node entry points so you can send consistent data from any surface.

npmnpm
Version
0.1.1
Version published
Weekly downloads
78
11.43%
Maintainers
1
Weekly downloads
 
Created
Source

Crelora Mark SDK

Mark is Crelora's lightweight attribution SDK for capturing user journeys, conversions, and consent across browsers and server-side runtimes. The npm package includes both browser and Node entry points so you can send consistent data from any surface.

Use it to feed OneLence with first‑party behavioral and conversion data so you can build analytics, insights, signals, and decisions on top of a unified event stream.

API keys and documentation

  • Keys: Publishable keys (pk_…) for browser and secret keys (sk_…) for server-side use are available in the OneLence dashboard: API keys.
  • Guides: For integration patterns, alternative integration types (e.g. server-only, tag managers), and deeper technical documentation, see the Integrations overview.

Installation

npm install @crelora/mark
# or
yarn add @crelora/mark

Runtime Imports

  • Browser runtime: import { Mark } from '@crelora/mark'
  • Node runtime: import { createNodeMark } from '@crelora/mark/node'

CDN / Script Tag Usage

You can also drop the SDK directly into your browser applications via a script tag. This exposes the global window.Mark object.

<!-- Use a CDN like unpkg or jsdelivr -->
<script src="https://unpkg.com/@crelora/mark@latest/dist/browser.umd.js"></script>

<script>
  // Mark is available globally
  Mark.init({
    key: 'pk_xxxxx',
    // ... configuration
  });

  Mark.track('Page View');
</script>

Browser Quickstart

import { Mark } from '@crelora/mark';

Mark.init({
  key: 'pk_xxxxx',
  require_consent: 'auto',
  cross_domain: { cookie_domain: '.example.com' },
  site_id: 'uuid-...',           // Optional: associate events with a registered site
  site_host: 'shop.example.com', // Optional: site host for audit/debug
  autocapture: { pageview: true }, // Optional: auto-emit page_view on load and SPA route changes
});

Mark.identify('user_123', { 
  email: 'customer@example.com',
  display_name: 'John Doe',
  language: 'en-US'
});
Mark.track('Checkout Started', { value: 12900, currency: 'usd' });
Mark.setConsent('granted');

// Per-event site overrides (optional)
Mark.track('Conversion', {
  site_id: 'different-site-uuid',  // Overrides init config for this event
  site_host: 'other.example.com',
  value: 5000,
});

Mark.init should be called once during app bootstrap. Subsequent calls to track, identify, or setConsent reuse the same client instance.

Node / Server Usage

import { createNodeMark } from '@crelora/mark/node';

const mark = createNodeMark({
  key: process.env.MARK_SECRET_KEY!,
  site_id: process.env.MARK_SITE_ID,     // Optional: associate events with a registered site
  site_host: process.env.MARK_SITE_HOST, // Optional: site host for audit/debug
});

mark.track('Server Conversion', {
  visitor_id: 'vis_abc',
  order_id: 'ord_789',
  value: 19900,
});

The Node factory accepts optional custom storage or transport adapters so you can plug the SDK into queues or serverless environments.

Available Methods

  • Mark.init(config) / createNodeMark(config) – bootstraps the client with your publishable or secret key.
  • track(eventName, payload?) – records custom events with arbitrary properties (numbers, strings, arrays, objects). Use site_id and site_host for per-event site overrides.
  • conversion(eventName, payload?) – records conversion events (same endpoint path as track, with is_conversion: true for backend compatibility).
  • identify(userId, traits?) – ties a known user identifier to previous anonymous activity. Recommended traits: email, display_name, language. Custom traits are also supported.
  • setConsent(status) – enforces consent gating; pass 'granted' or 'denied'.
  • getVisitorId() – returns the current pseudonymous visitor ID when available. On the browser, returns undefined until consent is granted when require_consent is set. Use it to send the ID to your backend (e.g. in a header or body) for server-side attribution when you don't have an authenticated user ID.
  • flush() – flushes queued/persisted delivery items.
  • reset() – clears user/session/attribution state and rotates visitor identity for logout flows.
  • getStats() – returns runtime delivery stats { queued, sent, failed, dropped }.

Reserved SDK fields (for example event_name, user_id, consent_state, and internal identity metadata) are sanitized from user payloads/traits and cannot override SDK-managed values.

Automatic Attribution Tracking

The SDK automatically captures and persists the following URL parameters:

  • UTM keys: utm_source, utm_medium, utm_campaign, utm_term, utm_content
  • Referral aliases: ref, referral, affiliate_id (normalized to ref)
  • Generic IDs: click_id, ch_click_id, cid, campaign_id
  • Paid platform IDs: gclid, gbraid, wbraid, dclid, msclkid, fbclid, ttclid, twclid, li_fat_id

These parameters are included in every tracked event to ensure proper attribution.

Capture is evaluated at SDK initialization and refreshed before each auto page view emit when autocapture.pageview + route tracking are enabled.

  • If consent is not yet granted (require_consent: true or 'auto'), attribution is kept in runtime memory and not persisted.
  • After consent is granted, pending in-memory attribution and current URL attribution are persisted.

Custom Query Param Capture

You can expand the default attribution allowlist or opt into full query capture:

Mark.init({
  key: 'pk_xxxxx',
  capture_query_params: ['sub_id1', 'sub_id2', 'publisher_code'],
  // Optional:
  // capture_all_query_params: true,
  // query_param_denylist: ['email', 'token', 'auth'],
  // max_captured_query_params: 30,
  // max_query_param_value_length: 256,
});

Configuration Reference

All config options use snake_case. Stored event payloads and database columns match 1:1.

OptionTypeDescription
keystringPublishable (browser) or secret (server) key from OneLence API keys.
debugbooleanEnables verbose console logging to help with integration tests.
before_send(event) => event | nullMutate/redact payloads before send, or return null to drop events.
on_error(error, event?) => voidHook for transport and queue failures.
sample_ratenumberFraction (0..1) for track event sampling. identify and conversion are never sampled.
honor_dntbooleanWhen true, blocks tracking when browser DNT/GPC is enabled.
session_timeout_msnumberInactivity window for rotating session_id (default 30 minutes).
request_timeout_msnumberHTTP timeout per request in milliseconds (default 10000).
rotate_visitor_on_consent_changebooleanRotate visitor_id after denied -> granted transition.
batching{ enabled?: boolean, max_size?: number, flush_interval_ms?: number, endpoint_path?: string }Optional batch mode (/events by default).
require_consentboolean | 'auto'true blocks tracking until consent is granted, 'auto' requires stored granted consent and treats missing consent as denied, default false ('auto' recommended for production).
consent_source{ type: 'tcf', purposes: number[] }Optional IAB TCF v2 integration: the SDK listens for CMP updates and only allows tracking when the listed numeric purpose IDs are consented. Combine with require_consent and setConsent as your legal team requires.
autocapture{ pageview?: boolean, click?: boolean | { selector?: string }, form_submit?: boolean, outbound_link?: boolean, scroll_depth?: boolean, web_vitals?: boolean }Auto-capture toggles for page views and optional interaction/perf signals.
track_route_changesbooleanWhen autocapture.pageview is true, also emits on SPA route changes (pushState/replaceState/popstate); defaults to true.
include_page_contextbooleanWhen true (default), enriches events with page, title, referrer, site (full url is only sent if you pass it explicitly in payload).
cross_domainCrossDomainConfigControls cookie domain, bridge URL, and allowlist for multi-domain attribution.
site_idstringOptional UUID for associating events with a registered site. Included in all event payloads as site_id.
site_hoststringOptional site host for audit/debug purposes. Included in all event payloads as site_host. If not provided, browser SDK uses window.location.host.
capture_query_paramsstring[]Additional query keys to capture for attribution (merged into the default allowlist).
capture_all_query_paramsbooleanCapture all query params after denylist/limits. Defaults to false.
query_param_denyliststring[]Query keys that are never captured (exact-key matching; default includes sensitive keys like email, token, password).
max_captured_query_paramsnumberMaximum number of captured query keys stored per visitor (default 30).
max_query_param_value_lengthnumberMaximum stored length per captured query value (default 256).

Server runtimes can also pass storage, storageDefaults, or transport via createNodeMark to fully control persistence and delivery.

These behaviors matter for compliance-sensitive setups (GDPR-style consent, CMPs, enterprise security reviews):

  • Consent gating: Use require_consent: true or 'auto' so events and identify only run after a positive consent signal. In 'auto' mode, missing consent is treated as denied until setConsent('granted').
  • TCF v2: Set consent_source: { type: 'tcf', purposes: [/* IAB purpose IDs */] } so tracking follows your CMP’s current purpose consents (the SDK subscribes to CMP updates rather than relying on a one-time read).
  • Withdrawal: setConsent('denied') stops tracking and clears stored attribution plus cookie-backed visitor identity where applicable.
  • Stricter identity hygiene: Enable rotate_visitor_on_consent_change if you want a fresh visitor_id after a denied → granted transition.
  • DNT / GPC: honor_dnt: true blocks tracking when the browser reports Do Not Track or Global Privacy Control.
  • Data minimization: Use before_send to strip or redact fields before they leave the client; use on_error for observability without logging raw payloads.
  • Payloads cannot bypass consent via event properties; reserved fields are sanitized.
  • Pre-consent attribution: URL attribution is held in memory only until consent is granted, then persisted.
  • Cross-domain: First-party iframe bridges keep identifiers under your control.
  • Delivery without long-lived local queues: Failed sends can be retried from a browser outbox with a 48-hour TTL; on tab hide / unload, pending items are flushed with sendBeacon where possible to improve delivery without weakening consent checks.
  • IP / geo: IP is not read in the browser; it is taken server-side, hashed, and used for coarse geo only when allowed by consent and tenant settings.

For product-level privacy commitments and processor terms, rely on your OneLence agreement and documentation; this README describes SDK behavior only.

Visitor ID for server attribution

When you don't have an authenticated user ID, you can pass the SDK's visitor ID to your backend so server-side events (e.g. checkout, webhooks) are attributed to the same visitor as browser events.

Browser: Call Mark.getVisitorId() after init. If you use require_consent: true or 'auto', it returns undefined until consent is granted. Once available, send it in a header or request body to your API and use it as the visitor_id when calling the Node SDK or your ingestion.

Node: Call mark.getVisitorId() to read the visitor ID from the storage you passed to createNodeMark (e.g. from storageDefaults.visitor_id). Use it to associate server events with the same visitor.

The visitor ID is a pseudonymous, SDK-scoped identifier. Do not use it as a cross-site or long-term user identity; use it only for joining browser and server events within your attribution flow.

User Identification

The identify() method links anonymous visitors to known users. Recommended traits:

  • email (string) - User's email address. Will be hashed server-side for privacy.
  • display_name (string) - User's display name or full name.
  • language (string) - User's preferred language code (e.g., 'en', 'en-US', 'fr').
  • phone (string) - User's phone number. Will be hashed server-side for privacy.

You can also include any custom traits as key-value pairs. All traits are stored in the user profile and can be used for segmentation and personalization.

Mark.identify('user_123', {
  email: 'customer@example.com',
  display_name: 'John Doe',
  language: 'en-US',
  plan: 'premium',
  signup_date: '2024-01-15',
});

Page Views

  • Event name: page_view (canonical). Use display names in your product UI if you prefer human-readable labels.
  • Autocapture (optional): set autocapture: { pageview: true } (and optionally track_route_changes: true) to emit on first load and SPA route changes. If consent is required and not yet granted, initial pageview is deferred and emitted once consent is granted.
  • All SDK config and event fields use snake_case (site_id, site_host, etc.) and map directly to stored payloads and database columns.

Support

Need help? Reach out through your account team or file a ticket via the OneLence dashboard. Please include the SDK version, runtime (browser or Node), and any reproduction steps so we can assist quickly.

FAQs

Package last updated on 22 Apr 2026

Related posts