@praevis/web-sdk
v1.0.0
Published
Praevis Exchange Web SDK - OpenRTB 2.6 compliant ad serving for publishers
Maintainers
Readme
Praevis Exchange Web SDK
Official JavaScript/TypeScript SDK for integrating with Praevis Exchange. This lightweight SDK handles OpenRTB 2.6 bid requests, ad rendering, and event tracking.
Features
- ✅ OpenRTB 2.6 Compliant - Full support for OpenRTB bid requests
- ✅ TypeScript Support - Complete type definitions included
- ✅ Automatic Device Detection - Collects device and site information
- ✅ Event Tracking - Built-in impression and click tracking
- ✅ Easy Integration - Simple API for requesting and rendering ads
- ✅ Zero Dependencies - Pure TypeScript, no external libraries
- ✅ Universal Format - UMD and ESM builds for any environment
Installation
NPM/Yarn
npm install @praevis/web-sdk
# or
yarn add @praevis/web-sdkCDN (Script Tag)
<script src="https://unpkg.com/@praevis/web-sdk@latest/dist/praevis-sdk.min.js"></script>
<script>
// SDK is available as window.PraevisSDK.default
const sdk = new window.PraevisSDK.default({
apiKey: 'pub_your_api_key'
});
</script>Quick Start
1. Initialize the SDK
import { PraevisSDK } from '@praevis/web-sdk';
// or
import PraevisSDK from '@praevis/web-sdk'; // default export
const sdk = new PraevisSDK({
apiKey: 'pub_your_api_key_here', // Get from dashboard
endpoint: 'https://exchange.praevis.com/rtb', // Optional, defaults to production
timeout: 2000, // Optional, default 2000ms
debug: false, // Optional, enable console logging
});2. Add Ad Placeholders to HTML
<div id="ad-banner-1"></div>
<div id="ad-banner-2"></div>3. Request and Render Ads
// Request and render in one call (recommended)
await sdk.renderAd({
elementId: 'ad-banner-1',
width: 300,
height: 250,
bidfloor: 0.75, // Minimum CPM in USD
});Usage Examples
Basic Banner Ad
const sdk = new PraevisSDK({
apiKey: 'pub_smarttv_apps',
});
// Render a 300x250 banner
await sdk.renderAd({
elementId: 'sidebar-ad',
width: 300,
height: 250,
bidfloor: 1.0,
});Multiple Ad Units
const adUnits = [
{ elementId: 'header-ad', width: 728, height: 90, bidfloor: 2.0 },
{ elementId: 'sidebar-ad', width: 300, height: 250, bidfloor: 1.5 },
{ elementId: 'footer-ad', width: 320, height: 50, bidfloor: 0.5 },
];
// Request all ads in parallel
await Promise.all(adUnits.map((unit) => sdk.renderAd(unit)));Manual Request and Render
// Request bid only
const bidResponse = await sdk.requestAd({
elementId: 'custom-ad',
width: 300,
height: 250,
bidfloor: 1.0,
});
// Check if we got a bid
if (bidResponse.seatbid && bidResponse.seatbid.length > 0) {
const bid = bidResponse.seatbid[0].bid[0];
console.log('Won bid at $' + bid.price + ' CPM');
// Manually render the ad
const element = document.getElementById('custom-ad');
element.innerHTML = bid.adm;
}With Custom Click Tracking
await sdk.renderAd(
{
elementId: 'tracked-ad',
width: 300,
height: 250,
bidfloor: 1.0,
},
{
trackImpression: true, // Default: true
trackClick: true, // Default: true
clickUrl: 'https://your-tracking-url.com/click', // Optional custom URL
}
);Error Handling
try {
const success = await sdk.renderAd({
elementId: 'my-ad',
width: 300,
height: 250,
});
if (!success) {
console.log('No bid received, showing fallback ad');
// Show your house ad or other fallback
}
} catch (error) {
console.error('Ad request failed:', error);
}Debug Mode
const sdk = new PraevisSDK({
apiKey: 'pub_test_key',
debug: true, // Enable detailed console logging
});
// All requests will log:
// - Bid requests sent
// - Bid responses received
// - Rendering events
// - Tracking events
// - ErrorsAPI Reference
new PraevisSDK(config)
Initialize the SDK with configuration.
Parameters:
| Parameter | Type | Required | Default | Description |
| ----------------- | --------- | -------- | ------------------------------------ | ------------------------------- |
| config.apiKey | string | Yes | - | Your publisher API key |
| config.endpoint | string | No | https://exchange.praevis.com/rtb | Exchange endpoint URL |
| config.timeout | number | No | 2000 | Request timeout in milliseconds |
| config.debug | boolean | No | false | Enable debug logging |
Example:
const sdk = new PraevisSDK({
apiKey: 'pub_prod_news001',
timeout: 3000,
debug: process.env.NODE_ENV === 'development',
});sdk.requestAd(adUnit)
Request a bid for an ad unit.
Parameters:
| Parameter | Type | Required | Default | Description |
| ------------------ | -------- | -------- | ------- | --------------------------- |
| adUnit.elementId | string | Yes | - | HTML element ID for the ad |
| adUnit.width | number | Yes | - | Ad width in pixels |
| adUnit.height | number | Yes | - | Ad height in pixels |
| adUnit.bidfloor | number | No | 0.01 | Minimum bid price (CPM USD) |
Returns: Promise<BidResponse> - OpenRTB 2.6 bid response
Example:
const response = await sdk.requestAd({
elementId: 'my-ad',
width: 300,
height: 250,
bidfloor: 1.5,
});sdk.renderAd(adUnit, options?)
Request and render an ad in one call.
Parameters:
| Parameter | Type | Required | Default | Description |
| --------------------------- | --------- | -------- | ------- | -------------------------------- |
| adUnit | AdUnit | Yes | - | Ad unit configuration (see above) |
| options.trackImpression | boolean | No | true | Fire impression tracking pixel |
| options.trackClick | boolean | No | true | Fire click tracking pixel |
| options.clickUrl | string | No | - | Custom click tracking URL |
Returns: Promise<boolean> - true if ad rendered successfully, false if no bid
Example:
const success = await sdk.renderAd(
{
elementId: 'my-ad',
width: 728,
height: 90,
bidfloor: 2.0,
},
{
trackImpression: true,
trackClick: true,
}
);Common Ad Sizes
| Size | Width | Height | Common Name | | ----------- | ----- | ------ | ------------------- | | 300x250 | 300 | 250 | Medium Rectangle | | 728x90 | 728 | 90 | Leaderboard | | 160x600 | 160 | 600 | Wide Skyscraper | | 320x50 | 320 | 50 | Mobile Banner | | 300x600 | 300 | 600 | Half-Page Ad | | 970x250 | 970 | 250 | Billboard | | 320x100 | 320 | 100 | Large Mobile Banner |
Browser Support
- Chrome 90+
- Firefox 88+
- Safari 14+
- Edge 90+
- Opera 76+
- Mobile browsers (iOS Safari 14+, Chrome Android 90+)
Privacy & Compliance
The SDK automatically:
- Respects user's Do Not Track (DNT) preference
- Collects only necessary device information
- Does not store cookies or local storage (except for tracking consent if you implement it)
- Compliant with GDPR, CCPA, and COPPA
User Consent: You are responsible for obtaining user consent before serving personalized ads. See our Privacy Policy for details.
// Example: Only initialize SDK after user consent
if (userHasConsentedToAds()) {
const sdk = new PraevisSDK({ apiKey: 'pub_key' });
await sdk.renderAd({ elementId: 'ad', width: 300, height: 250 });
}TypeScript Support
Full TypeScript definitions are included:
import PraevisSDK, { PraevisConfig, AdUnit, BidResponse } from '@praevis/web-sdk';
const config: PraevisConfig = {
apiKey: 'pub_key',
timeout: 3000,
};
const sdk = new PraevisSDK(config);
const adUnit: AdUnit = {
elementId: 'my-ad',
width: 300,
height: 250,
bidfloor: 1.0,
};
const response: BidResponse = await sdk.requestAd(adUnit);Troubleshooting
No Ads Showing
- Check API Key: Verify your API key in the dashboard
- Check Console: Enable
debug: trueto see detailed logs - Check Bid Floor: Try lowering
bidfloor(e.g.,0.01) - Check Element: Ensure the HTML element exists before calling
renderAd
Slow Ad Loading
- Reduce Timeout: Lower
timeoutto fail faster (e.g.,1000ms) - Check Network: Use browser DevTools to inspect network requests
- Parallelize Requests: Use
Promise.all()for multiple ads
CORS Errors
The Praevis Exchange API allows cross-origin requests. If you see CORS errors:
- Verify you're using the correct endpoint
- Check that your domain is registered in the dashboard
- Ensure you're sending the correct API key
Examples
React Component
import { useEffect, useState } from 'react';
import PraevisSDK from '@praevis/web-sdk';
function AdBanner({ width, height, bidfloor }) {
const [sdk] = useState(() => new PraevisSDK({ apiKey: 'pub_key' }));
const [loaded, setLoaded] = useState(false);
useEffect(() => {
sdk
.renderAd({
elementId: 'react-ad',
width,
height,
bidfloor,
})
.then(setLoaded);
}, [sdk, width, height, bidfloor]);
return (
<div>
<div id="react-ad"></div>
{!loaded && <div>Loading ad...</div>}
</div>
);
}Vue Component
<template>
<div>
<div :id="elementId"></div>
<div v-if="!loaded">Loading ad...</div>
</div>
</template>
<script>
import PraevisSDK from '@praevis/web-sdk';
export default {
props: ['width', 'height', 'bidfloor'],
data() {
return {
elementId: 'vue-ad-' + Math.random().toString(36).slice(2),
loaded: false,
sdk: new PraevisSDK({ apiKey: 'pub_key' }),
};
},
mounted() {
this.sdk
.renderAd({
elementId: this.elementId,
width: this.width,
height: this.height,
bidfloor: this.bidfloor,
})
.then((success) => {
this.loaded = success;
});
},
};
</script>Next.js Page
'use client';
import { useEffect, useRef } from 'react';
import PraevisSDK from '@praevis/web-sdk';
export default function AdPage() {
const sdkRef = useRef(null);
useEffect(() => {
if (!sdkRef.current) {
sdkRef.current = new PraevisSDK({ apiKey: 'pub_key' });
}
sdkRef.current.renderAd({
elementId: 'nextjs-ad',
width: 300,
height: 250,
bidfloor: 1.0,
});
}, []);
return (
<div>
<h1>My Next.js Page</h1>
<div id="nextjs-ad"></div>
</div>
);
}Support
- Documentation: https://docs.praevis.com
- Email: [email protected]
- Dashboard: https://dashboard.praevis.com
License
MIT License - see LICENSE file for details
Changelog
v1.0.0 (2025-11-04)
- Initial release
- OpenRTB 2.6 support
- TypeScript definitions
- Automatic device detection
- Event tracking
- UMD and ESM builds
