npm Integration
Prerequisites
- Active
siteKey. - API URL ending with
/api/v1. - Client-side lifecycle hook where runtime can initialize once.
- Decision on global compatibility (
exposeGlobal) or instance-only usage.
Currency rule: use ISO-4217 uppercase codes and replace SITE_CURRENCY in examples with your configured site currency.
Installation
npm install @selwise/widget
Initialization
import Selwise from '@selwise/widget';
const widget = new Selwise();
await widget.init({
siteKey: 'YOUR_SITE_KEY',
apiUrl: 'https://api.selwise.com/api/v1',
exposeGlobal: true,
});
Rules:
- Import and constructor are SSR-safe.
init()must run in browser runtime.- Keep one shared instance per app shell.
Single-instance example:
let widget: Selwise | null = null;
export async function ensureSelwise(siteKey: string, apiUrl: string) {
if (widget) return widget;
widget = new Selwise();
await widget.init({ siteKey, apiUrl, exposeGlobal: true });
return widget;
}
export function disposeSelwise() {
widget?.destroy();
widget = null;
}
Identity and Consent
await widget.identify('user_42', { email: 'user@example.com' });
await widget.setTraits({ plan: 'pro', locale: 'en' });
console.log(widget.getSiteUserId());
console.log(widget.getVisitorId());
console.log(widget.getSessionId());
widget.grantConsent({ analytics: true, marketing: true, preferences: true });
widget.revokeConsent(['marketing']);
Event Sending
widget.track('product_view', {
entityType: 'product',
entityId: 'SKU-123',
metadata: { productItemCode: 'SKU-123', title: 'Runner Pro', price: 149.9 },
});
widget.pushDataLayer({
event: 'checkout_begin',
checkout: { step: 1, basketId: 'cart_001', total: 149.9, currency: 'SITE_CURRENCY' },
});
For full event family coverage:
Order Tracking
await widget.trackOrder({
orderId: 'ORDER-1001',
currency: 'SITE_CURRENCY',
total: 149.9,
items: [{ productItemCode: 'SKU-123', quantity: 1, unitPrice: 149.9 }],
});
Search and Recommendation Usage
widget.pushDataLayer({
event: 'search_query',
search: { query: 'running shoes', results: 120 },
});
widget.pushDataLayer({
event: 'widget_impression',
custom: { params: { widgetId: 'widget_home_1' } },
});
Verification Checklist
widget.siteKeyandwidget.apiUrlmatch environment.widget.getVisitorId()andwidget.getSessionId()return values.events/batchandordersprobes succeed.- Consent state transitions are visible.
- No duplicate runtime instances in client shell.
Full runbook: Verification
Troubleshooting (Common)
window.Selwiseundefined in npm mode.
exposeGlobalnot enabled or init not completed.
- Duplicate events/widgets.
- Multiple runtime instances from route-level mounts.
init()appears no-op.
- Called in server runtime or with invalid/missing
siteKey.
Full matrix: Integration Troubleshooting
Production Go-Live Checklist
- One shared runtime instance pattern implemented.
-
init()only runs in browser/client lifecycle. - Canonical event payloads validated.
-
trackOrderidempotency byorderIdhandled. - Verification probes pass in staging.