@journiq/web-sdk
v0.3.1
Published
Journiq Web SDK — deep linking, attribution, event tracking, and web vitals for websites
Maintainers
Readme
Features
- Deep Linking — deferred deep link matching via device fingerprint
- Event Tracking — custom events with offline queue and automatic retry
- Web Vitals — automatic collection of TTFB, FCP, LCP, INP, CLS with full attribution
- Page View Tracking — automatic page views with SPA navigation support
- Link Management — create, list, and retrieve short links
- Offline Queue — localStorage-based queue with batch flushing and
sendBeaconon page unload
Installation
npm install @journiq/web-sdkCDN / Script Tag
<script src="https://cdn.jsdelivr.net/npm/@journiq/web-sdk/dist/index.iife.js"></script>
<script>
Journiq.init({ apiKey: 'jq_pub_...', appId: 'your-app-id' });
</script>Quick Start
import { init, getInstance } from '@journiq/web-sdk';
// Initialize (typically in your app's entry point)
init({
apiKey: 'jq_pub_...',
appId: 'your-app-id',
// Optional — all default to true
autoTrackVitals: true,
autoTrackPageViews: true,
});
// Track a custom event
const journiq = getInstance();
journiq.events.track('button_click', { buttonId: 'cta-hero' });
// Check for deferred deep link
const deepLink = await journiq.deepLinks.checkDeferredDeepLink();
if (deepLink) {
console.log('Matched deep link:', deepLink.targetUrl);
}API Reference
init(options)
Initialize the SDK. Must be called once before using any other API.
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| apiKey | string | required | Public API key (jq_pub_...) or app key (jq_app_...) |
| appId | string | required | Your Journiq app ID |
| baseUrl | string | 'https://api.journiq.io' | API base URL |
| autoTrackVitals | boolean | true | Automatically collect Web Vitals |
| autoTrackPageViews | boolean | true | Automatically track page views |
| flushIntervalMs | number | 30000 | Queue flush interval in milliseconds |
| maxQueueSize | number | 1000 | Maximum queued events before FIFO eviction |
getInstance()
Returns the JourniqInstance with access to all modules:
instance.events
// Track a custom event
instance.events.track('purchase', { amount: 29.99, currency: 'USD' });
// Track a page view manually
instance.events.trackPageView();
// Flush the event queue immediately
await instance.events.flush();instance.deepLinks
// Check for deferred deep link (runs once per browser)
const match = await instance.deepLinks.checkDeferredDeepLink();
// Parse a deep link URL
const parsed = instance.deepLinks.parseDeepLink('https://example.com/promo?code=123');instance.links
// Create a short link
const link = await instance.links.create({
targetUrl: 'https://example.com/landing',
title: 'Summer Sale',
});
// List links
const links = await instance.links.list();
// Get a specific link
const link = await instance.links.get('link-id');
// Get link stats
const stats = await instance.links.getStats('link-id');instance.analytics
// Get app configuration and stats
const config = await instance.analytics.getAppConfig();getVitals()
import { getInstance } from '@journiq/web-sdk';
// Get collected Web Vitals snapshot
const vitals = getInstance().getVitals();
// { ttfb: { value: 120, rating: 'good' }, lcp: { ... }, ... }destroy()
import { destroy } from '@journiq/web-sdk';
// Clean up listeners, timers, and flush pending events
destroy();Web Vitals
When autoTrackVitals is enabled (default), the SDK automatically collects all five Core Web Vitals using the web-vitals library with full attribution:
| Metric | Event Name | Attribution Data |
|--------|-----------|-----------------|
| TTFB | web_vital_ttfb | DNS, connection, TLS, request/response timing |
| FCP | web_vital_fcp | TTFB breakdown, load state, render blocking |
| LCP | web_vital_lcp | Element, URL, TTFB breakdown, resource load |
| INP | web_vital_inp | Event target, type, input/processing/presentation delays |
| CLS | web_vital_cls | Largest shift target and timing |
Each vital is tracked as a custom event with the metric value, rating (good / needs-improvement / poor), and detailed attribution metadata.
SPA Support
The SDK automatically detects client-side navigation by intercepting history.pushState, history.replaceState, and popstate events. Each navigation triggers a page view event with the new URL.
Offline Queue
Events are stored in localStorage under the key journiq_event_queue and flushed:
- Every 30 seconds (configurable via
flushIntervalMs) - When the browser comes back online
- On page hide / visibility change (via
sendBeacon)
Queue limits:
- Max size: 1000 events (FIFO eviction)
- Max retries: 3 per event
- Expiry: 7 days
- Batch size: 100 events per flush
Browser Support
- All modern browsers (Chrome, Firefox, Safari, Edge)
- ES2020+ required
- Web Vitals attribution requires Chromium-based browsers
Development
npm install
npm run build # Build ESM, CJS, and IIFE bundles
npm run dev # Watch mode
npm run typecheck # Type-check without emittingLicense
MIT
