@adxensor/publisher-sdk 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +299 -0
  3. package/package.json +37 -4
package/CHANGELOG.md ADDED
@@ -0,0 +1,24 @@
1
+ # Changelog
2
+
3
+ All notable changes to `@adxensor/publisher-sdk` are documented here.
4
+
5
+ ## [1.0.0] — 2025-03-29
6
+
7
+ ### Initial release
8
+
9
+ - CDN IIFE bundle (`tag.js`) — drop-in `<script>` tag, no dependencies
10
+ - npm package — ESM + CJS + TypeScript declarations
11
+ - AdSense-style `<ins class="adxensor">` slot markup
12
+ - `data-ad-format`, `data-ad-slot`, `data-ad-client` attributes
13
+ - Push queue: `(window.adxensor = window.adxensor || []).push({})`
14
+ - Lazy loading via `IntersectionObserver` (200 px root margin)
15
+ - Viewability tracking — IAB MRC standard (50% visible ≥ 1 s)
16
+ - Impression deduplication — once per adId × session
17
+ - Click deduplication — 500 ms debounce
18
+ - Events via `navigator.sendBeacon` with `fetch keepalive` fallback
19
+ - Singleton `AdXensor.getInstance()` — one instance per page
20
+ - MutationObserver DOM watcher — SPA / dynamic content support
21
+ - State machine on `<ins>` element (`data-adx-state`) — idempotent fills
22
+ - Language normalisation: `fr-FR` → `fr`, `en-US` → `en`
23
+ - Country, browser and OS resolved server-side from IP / User-Agent
24
+ - Direct communication with `core.adxensor.com` — no client-api proxy
package/README.md ADDED
@@ -0,0 +1,299 @@
1
+ # @adxensor/publisher-sdk
2
+
3
+ **AdXensor Publisher SDK** — Serve ads, track impressions, clicks, views and pageviews directly from any website or web app.
4
+ Works as a CDN `<script>` snippet **or** as an npm package. Zero runtime dependencies.
5
+
6
+ [![npm version](https://img.shields.io/npm/v/@adxensor/publisher-sdk.svg)](https://www.npmjs.com/package/@adxensor/publisher-sdk)
7
+ [![License](https://img.shields.io/badge/license-UNLICENSED-red.svg)](https://adxensor.com)
8
+
9
+ ---
10
+
11
+ ## Table of Contents
12
+
13
+ - [How it works](#how-it-works)
14
+ - [CDN snippet (recommended)](#cdn-snippet-recommended)
15
+ - [npm package](#npm-package)
16
+ - [Ad slot attributes](#ad-slot-attributes)
17
+ - [Supported formats](#supported-formats)
18
+ - [Events tracked](#events-tracked)
19
+ - [Advanced usage](#advanced-usage)
20
+ - [TypeScript](#typescript)
21
+ - [Requirements](#requirements)
22
+ - [Support](#support)
23
+
24
+ ---
25
+
26
+ ## How it works
27
+
28
+ ```
29
+ Publisher website AdXensor (core.adxensor.com)
30
+ ────────────────────────────────────────────────────────────────
31
+ 1. Page loads tag.js → Fires pageview event
32
+ 2. SDK finds <ins> slots → GET /v1/ad?zone=SIZE&site=ID
33
+ 3. Renders creative ← Returns image URL + click URL
34
+ 4. Ad enters viewport (50%) → POST /v1/events/impression
35
+ 5. Visible ≥ 1 second → POST /v1/events/view
36
+ 6. User clicks ad → POST /v1/events/click
37
+ Redirect → Advertiser URL
38
+ ```
39
+
40
+ Country, browser and OS are resolved **server-side** from the visitor's IP and User-Agent — the SDK never reads or stores personal data.
41
+
42
+ ---
43
+
44
+ ## CDN snippet (recommended)
45
+
46
+ Paste once in your `<head>`, then place `<ins>` tags wherever you want ads.
47
+
48
+ ### 1. Load the SDK
49
+
50
+ ```html
51
+ <script async
52
+ src="https://cdn.adxensor.com/tag.js"
53
+ data-ad-client="pub-XXXXXXXX">
54
+ </script>
55
+ ```
56
+
57
+ Replace `pub-XXXXXXXX` with your **Site ID** from the AdXensor publisher dashboard.
58
+
59
+ ### 2. Place an ad slot
60
+
61
+ ```html
62
+ <ins class="adxensor"
63
+ style="display:block"
64
+ data-ad-slot="header-banner"
65
+ data-ad-format="728x90">
66
+ </ins>
67
+ ```
68
+
69
+ That's it. The SDK automatically fills every `<ins class="adxensor">` on the page.
70
+
71
+ ---
72
+
73
+ ### AdSense-style push (fill one slot at a time)
74
+
75
+ If you prefer to control when each slot loads — identical to Google AdSense:
76
+
77
+ ```html
78
+ <ins class="adxensor"
79
+ style="display:block"
80
+ data-ad-slot="sidebar"
81
+ data-ad-format="300x250">
82
+ </ins>
83
+ <script>
84
+ (window.adxensor = window.adxensor || []).push({});
85
+ </script>
86
+ ```
87
+
88
+ ### Pre-load queue (calls before the script is ready)
89
+
90
+ ```html
91
+ <script>
92
+ window.adxensor = window.adxensor || [];
93
+ window.adxensor.push({}); // queued, executed once tag.js is ready
94
+ </script>
95
+ <!-- tag.js can be anywhere on the page -->
96
+ <script async src="https://cdn.adxensor.com/tag.js" data-ad-client="pub-XXXXXXXX"></script>
97
+ ```
98
+
99
+ ---
100
+
101
+ ### CDN script attributes
102
+
103
+ | Attribute | Required | Description |
104
+ |---|---|---|
105
+ | `data-ad-client` | ✅ | Your Site ID from the publisher dashboard |
106
+ | `data-api-key` | — | Optional publisher API key for authenticated sites |
107
+ | `data-lazy-load` | — | Set to `"false"` to disable lazy loading |
108
+ | `data-debug` | — | Enables verbose console logs |
109
+
110
+ ---
111
+
112
+ ## npm package
113
+
114
+ Install if you use a bundler (Vite, webpack, Next.js, etc.).
115
+
116
+ ```bash
117
+ npm install @adxensor/publisher-sdk
118
+ ```
119
+
120
+ ### Basic setup
121
+
122
+ ```typescript
123
+ import { AdXensor } from '@adxensor/publisher-sdk';
124
+
125
+ const adx = new AdXensor({
126
+ siteId: 'pub-XXXXXXXX', // your Site ID
127
+ apiKey: 'YOUR_API_KEY', // optional
128
+ lazyLoad: true, // default: true
129
+ debug: false,
130
+ });
131
+
132
+ adx.init(); // fires pageview + fills all <ins class="adxensor"> slots
133
+ ```
134
+
135
+ ### Fill a specific slot programmatically
136
+
137
+ ```typescript
138
+ // By CSS selector
139
+ adx.defineSlot('#my-banner', { format: '300x250' });
140
+
141
+ // On a specific element
142
+ const el = document.getElementById('my-banner') as HTMLElement;
143
+ adx.fill(el, { format: '728x90' });
144
+ ```
145
+
146
+ ### Singleton (one instance per page)
147
+
148
+ ```typescript
149
+ import { AdXensor } from '@adxensor/publisher-sdk';
150
+
151
+ // Always returns the same instance
152
+ const adx = AdXensor.getInstance({ siteId: 'pub-XXXXXXXX' });
153
+ adx.init();
154
+ ```
155
+
156
+ ### React / Next.js example
157
+
158
+ ```tsx
159
+ 'use client';
160
+ import { useEffect } from 'react';
161
+ import { AdXensor } from '@adxensor/publisher-sdk';
162
+
163
+ export function AdSlot({ slot, format }: { slot: string; format: string }) {
164
+ useEffect(() => {
165
+ const adx = AdXensor.getInstance({ siteId: 'pub-XXXXXXXX' });
166
+ adx.defineSlot(`[data-ad-slot="${slot}"]`, { format });
167
+ }, [slot, format]);
168
+
169
+ return (
170
+ <ins
171
+ className="adxensor"
172
+ style={{ display: 'block' }}
173
+ data-ad-slot={slot}
174
+ data-ad-format={format}
175
+ />
176
+ );
177
+ }
178
+ ```
179
+
180
+ ---
181
+
182
+ ## Ad slot attributes
183
+
184
+ | Attribute | Description | Example |
185
+ |---|---|---|
186
+ | `class="adxensor"` | **Required.** Identifies the element as an ad slot | — |
187
+ | `style="display:block"` | **Required.** Prevents collapsed slots | — |
188
+ | `data-ad-slot` | Slot name (used for reporting) | `"header-banner"` |
189
+ | `data-ad-format` | Ad size. Defaults to `auto` | `"728x90"` |
190
+ | `data-ad-lazy` | Presence enables lazy loading for this slot | — |
191
+
192
+ ---
193
+
194
+ ## Supported formats
195
+
196
+ | Format | Size | Placement |
197
+ |---|---|---|
198
+ | `728x90` | 728 × 90 | Leaderboard — top/bottom of page |
199
+ | `970x90` | 970 × 90 | Super leaderboard |
200
+ | `970x250` | 970 × 250 | Billboard |
201
+ | `300x250` | 300 × 250 | Medium rectangle — sidebar / in-feed |
202
+ | `300x600` | 300 × 600 | Half page — sidebar |
203
+ | `160x600` | 160 × 600 | Wide skyscraper |
204
+ | `320x50` | 320 × 50 | Mobile banner |
205
+ | `320x100` | 320 × 100 | Large mobile banner |
206
+ | `468x60` | 468 × 60 | Full banner |
207
+ | `auto` | dynamic | Best fit for device + container width |
208
+
209
+ ---
210
+
211
+ ## Events tracked
212
+
213
+ All events are fired automatically. No manual instrumentation needed.
214
+
215
+ | Event | Trigger | Deduplication |
216
+ |---|---|---|
217
+ | **pageview** | Page load | Once per page load |
218
+ | **impression** | Ad rendered | Once per ad × session |
219
+ | **view** | Ad ≥ 50% visible for ≥ 1 second (IAB MRC) | Once per ad × session |
220
+ | **click** | User clicks the ad | 500 ms debounce |
221
+
222
+ Events are sent via `navigator.sendBeacon` (non-blocking, survives page unload). Falls back to `fetch` with `keepalive: true`.
223
+
224
+ ---
225
+
226
+ ## Advanced usage
227
+
228
+ ### Access lower-level APIs
229
+
230
+ ```typescript
231
+ import { AdXensorApi, Tracker, getSessionId } from '@adxensor/publisher-sdk';
232
+
233
+ const api = new AdXensorApi('https://core.adxensor.com/v1', 'YOUR_API_KEY');
234
+ const sessionId = getSessionId();
235
+ const tracker = new Tracker(api, 'pub-XXXXXXXX', sessionId);
236
+
237
+ // Manual event firing
238
+ tracker.pageview();
239
+ tracker.impression('adId', 'slotId', 'impressionToken');
240
+ tracker.view('adId', 'slotId');
241
+ tracker.click('adId', 'slotId', 'clickToken');
242
+ ```
243
+
244
+ ### Destroy and reset (SPA route changes)
245
+
246
+ ```typescript
247
+ adx.destroy(); // stop DOM observer, clear timers
248
+ AdXensor.reset(); // destroy + clear the singleton
249
+ ```
250
+
251
+ ---
252
+
253
+ ## TypeScript
254
+
255
+ The SDK is written in TypeScript and ships full type declarations.
256
+
257
+ ```typescript
258
+ import type {
259
+ AdXensorConfig,
260
+ SlotOptions,
261
+ AdFormat,
262
+ DeviceType,
263
+ AdResponse,
264
+ SlotState,
265
+ } from '@adxensor/publisher-sdk';
266
+
267
+ const config: AdXensorConfig = {
268
+ siteId: 'pub-XXXXXXXX',
269
+ lazyLoad: true,
270
+ };
271
+
272
+ const options: SlotOptions = {
273
+ format: '300x250',
274
+ lazy: false,
275
+ };
276
+ ```
277
+
278
+ ---
279
+
280
+ ## Requirements
281
+
282
+ | Environment | Minimum version |
283
+ |---|---|
284
+ | Node.js (npm build) | 18+ |
285
+ | Browser (CDN) | Chrome 58, Firefox 57, Safari 11, Edge 16 |
286
+ | IntersectionObserver | Required for lazy load + viewability (polyfill for IE) |
287
+
288
+ ---
289
+
290
+ ## Support
291
+
292
+ - **Dashboard** — [app.adxensor.com](https://app.adxensor.com)
293
+ - **Documentation** — [docs.adxensor.com](https://docs.adxensor.com)
294
+ - **Issues** — [GitLab Issues](https://gitlab.com/adxensor/adxensor-publisher-sdk/-/issues)
295
+ - **Email** — [support@adxensor.com](mailto:support@adxensor.com)
296
+
297
+ ---
298
+
299
+ © 2025 AdXensor. All rights reserved.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@adxensor/publisher-sdk",
3
- "version": "1.0.0",
4
- "description": "AdXensor publisher SDK — CDN tag and npm package for ad serving, impression, click, and view tracking",
3
+ "version": "1.0.2",
4
+ "description": "AdXensor publisher SDK — serve ads, track impressions, clicks, views and pageviews directly from any website or web app.",
5
5
  "license": "UNLICENSED",
6
6
  "private": false,
7
7
  "type": "module",
@@ -17,7 +17,9 @@
17
17
  },
18
18
  "files": [
19
19
  "dist/",
20
- "src/"
20
+ "src/",
21
+ "README.md",
22
+ "CHANGELOG.md"
21
23
  ],
22
24
  "scripts": {
23
25
  "build": "npm run build:cdn && npm run build:npm",
@@ -26,11 +28,42 @@
26
28
  "typecheck": "tsc --noEmit",
27
29
  "clean": "rm -rf dist"
28
30
  },
31
+ "keywords": [
32
+ "adxensor",
33
+ "advertising",
34
+ "ad-network",
35
+ "publisher",
36
+ "ads",
37
+ "banner",
38
+ "tracking",
39
+ "impression",
40
+ "click",
41
+ "viewability",
42
+ "cdn",
43
+ "monetization",
44
+ "display-advertising",
45
+ "adtech",
46
+ "africa"
47
+ ],
48
+ "author": {
49
+ "name": "AdXensor",
50
+ "url": "https://adxensor.com"
51
+ },
52
+ "repository": {
53
+ "type": "git",
54
+ "url": "https://gitlab.com/adxensor/adxensor-publisher-sdk.git"
55
+ },
56
+ "bugs": {
57
+ "url": "https://gitlab.com/adxensor/adxensor-publisher-sdk/-/issues",
58
+ "email": "support@adxensor.com"
59
+ },
60
+ "homepage": "https://docs.adxensor.com/publisher-sdk",
29
61
  "devDependencies": {
30
62
  "esbuild": "^0.21.0",
31
63
  "typescript": "^5.4.0"
32
64
  },
33
65
  "engines": {
34
66
  "node": ">=18"
35
- }
67
+ },
68
+ "sideEffects": false
36
69
  }