@alaasync/layersync-web
v0.4.0
Published
LayerSync browser SDK — conversion tracking + server-side CAPI delivery for any JS site.
Maintainers
Readme
@alaasync/layersync-web
Browser SDK for LayerSync — conversion tracking + server-side CAPI delivery for any JavaScript site.
One install, three credentials, zero per-platform integration code. Configuration lives in the LayerSync dashboard; this SDK enqueues events and ships them to LayerSync, which fans them out to Meta CAPI, Google Ads, GA4 Measurement Protocol, TikTok Events API, Pinterest, Snap, LinkedIn, X, and Reddit.
Install
npm install @alaasync/layersync-web
# pnpm add @alaasync/layersync-web
# yarn add @alaasync/layersync-webQuick start
import { LayerSync } from '@alaasync/layersync-web';
const ls = LayerSync.init({
siteId: 'YOUR_SITE_ID',
publishableKey: 'YOUR_API_KEY',
});
// Identify a known user (optional — events still work without this)
ls.identify('user_abc123', {
email: '[email protected]',
phone: '+15551234567',
first_name: 'Ada',
last_name: 'Lovelace',
});
// Track a purchase
ls.track('purchase', {
order_id: 'O-1024',
value: 99.95,
currency: 'USD',
items: [
{ item_id: 'SKU-A', name: 'Widget', quantity: 2, price: 29.99 },
{ item_id: 'SKU-B', name: 'Gadget', quantity: 1, price: 39.97 },
],
});
// Track a page view (auto-fires URL + title + referrer)
ls.page();
// Or with an explicit name
ls.page({ name: 'product_detail' });That's it. The event is queued locally, POSTed to LayerSync, and fanned out to every connected platform server-side. PII is SHA-256 hashed before transmission.
Canonical events
ls.track('page_view', { /* auto-filled */ });
ls.track('view_item', { item_id: 'SKU-A', value: 29.99, currency: 'USD' });
ls.track('view_item_list', { /* ... */ });
ls.track('view_category', { /* ... */ });
ls.track('search', { search_term: 'red widget' });
ls.track('add_to_cart', { items: [...], value: 29.99, currency: 'USD' });
ls.track('add_to_wishlist', { /* ... */ });
ls.track('begin_checkout', { items: [...], value: 99.95, currency: 'USD' });
ls.track('add_payment_info', { /* ... */ });
ls.track('purchase', { order_id: '...', value: 99.95, currency: 'USD', items: [...] });
ls.track('refund', { order_id: '...', value: 99.95, currency: 'USD' });
ls.track('lead', { email: '...' });
ls.track('sign_up', { /* ... */ });
ls.track('complete_registration', { /* ... */ });Custom event names are also accepted — they pass through to whichever platforms have a mapping for them in your LayerSync dashboard.
Consent
Default: granted. The SDK respects an explicit deny:
ls.setConsent(false); // halt everything
ls.setConsent(true); // resume
ls.setConsent({ meta: 'granted', tiktok: 'denied' }); // per-platformWhile granted=false, events are dropped at the SDK and no network requests fire. Set it back to true to resume; nothing is queued during denial.
Pagehide flush
The SDK auto-flushes on pagehide via navigator.sendBeacon so in-flight events aren't lost when the user closes the tab or navigates away. No setup required.
Frameworks
Using React / Next.js? Install @alaasync/layersync-react — it provides <LayerSyncProvider>, useLayerSync(), and auto-pageview tracking for Next.js App Router, Pages Router, and React Router v6.
Auth model
| Field | What |
|---|---|
| siteId | The numeric site identifier from your LayerSync dashboard. |
| publishableKey | The API key associated with that site. Safe to expose in browser bundles — only authorized to POST events for that site. |
| apiUrl | Defaults to https://layersynchub.com. Override for self-hosted instances or staging. |
Browser support
ES2019 baseline: Chrome 73+, Firefox 67+, Safari 12.1+, Edge 79+, iOS Safari 12.2+. No IE.
navigator.locks, CompressionStream, sendBeacon, and crypto.subtle are all feature-detected; the SDK works with reduced features when they're missing.
API reference
LayerSync.init(opts)
| Option | Type | Required | Default |
|---|---|---|---|
| siteId | string \| number | yes | — |
| publishableKey | string | yes | — |
| apiUrl | string | no | https://layersynchub.com |
| consoleLog | boolean | no | false |
| consent | boolean \| ConsentMap | no | granted |
Returns a LayerSyncClient. Subsequent calls return the same singleton.
client.identify(externalId, traits?)
ls.identify('user_abc123', {
email: '[email protected]', // SHA-256 before transmission
phone: '+15551234567', // E.164 normalized + SHA-256
first_name: 'Ada', // lowercased + SHA-256
last_name: 'Lovelace',
});Pass null to clear traits (e.g. on logout).
client.track(name, props?)
Returns void. Errors are absorbed — track() never throws, never blocks. Queued on network failure, retried with exponential backoff. Permanently undeliverable events drop after max_attempts.
client.page(opts?)
Equivalent to track('page_view', { name, url, title }) with auto-detection when the values aren't supplied.
client.setConsent(state)
See above.
client.flush()
Force-drain the queue. Returns a Promise that resolves when the current batch completes. Mostly useful in tests.
License
MIT.
