Browser Tracking
Lightweight client-side library (~2KB) for tracking impressions, clicks, and conversions in the browser.
Installation
The browser tracking library is included in the notpixel package:
npm
npm i notpixelImport from the /browser subpath:
import { createTracker } from 'notpixel/browser';Create a Tracker
import { createTracker } from 'notpixel/browser';
const tracker = createTracker({
publisherId: 'pub-xxx',
baseURL: 'https://api.notpixel.ai', // optional
timeoutMs: 5000, // optional
debug: false, // optional
});Track Impressions
Track when a user sees an ad:
await tracker.impression(impressionId);Auto-Track on Visibility
Use trackOnVisible to automatically track when an element enters the viewport:
import { trackOnVisible } from 'notpixel/browser';
const adElement = document.getElementById('ad-container');
const cleanup = trackOnVisible(adElement, impressionId, tracker, {
threshold: 0.5, // 50% visible (default)
once: true, // track only once (default)
});
// Call cleanup() to stop observing
cleanup();Uses IntersectionObserver for efficient viewport detection. Falls back to immediate tracking if not available.
Track Clicks
Track when a user clicks an ad:
await tracker.click(impressionId, {
metadata: { source: 'chat' }, // optional
});Click Handler Helper
Create a click handler with optional navigation:
import { createClickHandler } from 'notpixel/browser';
const handleClick = createClickHandler(impressionId, tracker, {
href: 'https://advertiser.com/landing',
newTab: true, // default
metadata: { source: 'sidebar' },
});
// Use in event listener
button.addEventListener('click', handleClick);
// Or in React
<button onClick={handleClick}>Learn More</button>Track Conversions
Track conversion events (signups, purchases, etc.):
await tracker.conversion(impressionId, {
type: 'signup', // required
valueCents: 0, // optional
externalId: 'order-1', // optional, for deduplication
metadata: {}, // optional
});Conversion Types
Common conversion types:
| Type | Description |
|---|---|
signup | User registration |
purchase | Completed purchase |
lead | Lead form submission |
trial | Trial started |
install | App install |
React Integration
import { useEffect, useRef } from 'react';
import { createTracker, trackOnVisible, createClickHandler } from 'notpixel/browser';
const tracker = createTracker({ publisherId: 'pub-xxx' });
function AdComponent({ ad, impressionId }) {
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
if (!ref.current) return;
return trackOnVisible(ref.current, impressionId, tracker);
}, [impressionId]);
const handleClick = createClickHandler(impressionId, tracker, {
href: ad.cta.url,
});
return (
<div ref={ref} className="ad">
<h3>{ad.headline}</h3>
<p>{ad.body}</p>
<button onClick={handleClick}>{ad.cta.label}</button>
</div>
);
}How It Works
The library uses navigator.sendBeacon for reliable tracking that works even when the page is closing:
User Action → sendBeacon (preferred) → NotPixel API
↓ (fallback)
fetch with keepalivesendBeacon ensures tracking data is sent even if the user navigates away immediately after clicking.
Check Ad Expiration
Ads expire after 60 minutes. Use isAdExpired to check before displaying:
import { isAdExpired, AD_EXPIRATION_MS } from 'notpixel/browser';
// Check if ad is expired
if (isAdExpired(ad)) {
// Fetch fresh ad from your backend
const freshAd = await fetchAdFromServer();
}
// Calculate remaining time
const remainingMs = ad.expiresAt - Date.now();
const remainingMinutes = Math.floor(remainingMs / 60000);Always check expiration before displaying an ad. Expired ads may have depleted budgets or outdated content.
Debug Mode
Enable logging to troubleshoot:
const tracker = createTracker({
publisherId: 'pub-xxx',
debug: true,
});
// Console: [notpixel] Beacon sent: /v1/impression {...}API Reference
createTracker(options)
| Option | Type | Default | Description |
|---|---|---|---|
publisherId | string | — | Your publisher ID |
baseURL | string | https://api.notpixel.ai | API base URL |
timeoutMs | number | 5000 | Request timeout |
debug | boolean | false | Enable logging |
trackOnVisible(element, impressionId, tracker, options)
| Option | Type | Default | Description |
|---|---|---|---|
threshold | number | 0.5 | Visibility threshold (0-1) |
once | boolean | true | Track only once |
Returns a cleanup function.
createClickHandler(impressionId, tracker, options)
| Option | Type | Default | Description |
|---|---|---|---|
href | string | — | URL to navigate to |
newTab | boolean | true | Open in new tab |
metadata | object | — | Custom metadata |
Returns an event handler function.
isAdExpired(ad)
Returns true if the ad’s expiresAt timestamp has passed.
AD_EXPIRATION_MS
Constant: 3600000 (60 minutes in milliseconds).