@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.
- package/CHANGELOG.md +24 -0
- package/README.md +299 -0
- 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
|
+
[](https://www.npmjs.com/package/@adxensor/publisher-sdk)
|
|
7
|
+
[](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.
|
|
4
|
-
"description": "AdXensor publisher SDK —
|
|
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
|
}
|