@wavebirdai/api 0.1.0-beta.16 → 0.1.0-beta.18
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 +39 -0
- package/README.md +9 -5
- package/dist/browser.d.ts +16 -0
- package/dist/browser.js +22 -1
- package/docs/web/generation.md +1 -1
- package/docs/web/nextjs.md +1 -1
- package/docs/web/reference.md +17 -1
- package/package.json +2 -1
- package/src/browser.d.ts +16 -0
- package/src/browser.js +22 -1
- package/templates/NEXT-SETUP.md +1 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.0-beta.18
|
|
4
|
+
|
|
5
|
+
- Prevent fractional clipping of the hosted ad frame at some device scales.
|
|
6
|
+
- Correct the consent language guidance: browser preference comes first, then the publisher fallback.
|
|
7
|
+
|
|
8
|
+
## 0.1.0-beta.17
|
|
9
|
+
|
|
10
|
+
- Optional `consentLocale` and `consentTheme` browser settings for the hosted consent dialog.
|
|
11
|
+
- Validate presentation settings before passing them to the renderer. Consent decisions, authorization and storage behavior are unchanged.
|
|
12
|
+
- Updated installation instructions and consent appearance reference.
|
|
13
|
+
|
|
14
|
+
## 0.1.0-beta.16
|
|
15
|
+
|
|
16
|
+
- Fixed diagnostic categories for renderer and observed CSP failures, without signed URLs or credentials.
|
|
17
|
+
- Optional placement positioning within the server-authorized formats, timing and size limits.
|
|
18
|
+
- Contain synchronous and asynchronous diagnostic callback failures.
|
|
19
|
+
- Expanded guidance for CSP, existing apps, session limits and separate secret ENV downloads.
|
|
20
|
+
|
|
21
|
+
## 0.1.0-beta.15
|
|
22
|
+
|
|
23
|
+
- Restore consent using the authoritative session revision after reload.
|
|
24
|
+
|
|
25
|
+
## 0.1.0-beta.14
|
|
26
|
+
|
|
27
|
+
- Reject wildcard origins during server configuration.
|
|
28
|
+
- Clarify complete Server ENV, required dependencies and integration into existing apps.
|
|
29
|
+
|
|
30
|
+
## 0.1.0-beta.13
|
|
31
|
+
|
|
32
|
+
- Shorter setup instructions with links to the API docs and Dashboard.
|
|
33
|
+
- Separate JavaScript, TypeScript and Python guides.
|
|
34
|
+
- Generation examples that preserve the app's request, response display and cancellation.
|
|
35
|
+
- Updated package description, documentation link and search keywords.
|
|
36
|
+
|
|
37
|
+
At `0.1.0-beta.13`, runtime code, exports and generator templates were unchanged from `0.1.0-beta.12`. Existing integrations remain on their selected version until explicitly upgraded.
|
|
38
|
+
|
|
39
|
+
The Python `0.1.0b9` source is included in the repository. Its released wheel is unchanged and is installed separately from npm.
|
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ Integrate Banner, Native and Clip ads into your AI app. wavebird handles ad deli
|
|
|
10
10
|
| --- | --- |
|
|
11
11
|
| JavaScript | `@wavebirdai/api`, follow the steps below |
|
|
12
12
|
| TypeScript | `@wavebirdai/api`, with included types and TypeScript examples |
|
|
13
|
-
| Python | `wavebird-publisher-server`, follow the [Python guide](python/README.md) |
|
|
13
|
+
| Python | `wavebird-publisher-server`, follow the [Python guide](https://github.com/wavebird-ai/api/blob/main/python/README.md) |
|
|
14
14
|
|
|
15
15
|
Native iOS and Android packages are not currently available. See [integration paths](https://wavebird.ai/api/integration-paths) for supported environments.
|
|
16
16
|
|
|
@@ -22,22 +22,26 @@ Use Node.js 20 or later on your server.
|
|
|
22
22
|
2. **Install the package.** Run this in your app's terminal, in the folder containing `package.json`:
|
|
23
23
|
|
|
24
24
|
```sh
|
|
25
|
-
npm install @wavebirdai/api@0.1.0-beta.
|
|
25
|
+
npm install @wavebirdai/api@0.1.0-beta.18
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
3. **Save the Server ENV from Overview, Integration step 2.** The key-only download is not the full configuration. Keep `WAVEBIRD_SECRET_KEY` and the stable, project-specific `WAVEBIRD_PREFERENCE_SECRET` out of browser code and Git. Include the saved `WAVEBIRD_PUBLIC_ORIGINS`.
|
|
29
|
-
4. **Connect the backend and frontend code.** Follow Dashboard's generated files to connect your app session, durable turn storage, model stream and ad slot. The source ZIP contains code only; download secret Server ENV separately. Keep the saved formats, sizes and timing. For apps with a Content Security Policy, follow the [exact renderer rules](docs/web/nextjs.md#generate-files).
|
|
29
|
+
4. **Connect the backend and frontend code.** Follow Dashboard's generated files to connect your app session, durable turn storage, model stream and ad slot. The source ZIP contains code only; download secret Server ENV separately. Keep the saved formats, sizes and timing. For apps with a Content Security Policy, follow the [exact renderer rules](https://github.com/wavebird-ai/api/blob/main/docs/web/nextjs.md#generate-files).
|
|
30
30
|
5. **Run your first Test ad.** Confirm that the ad appears and the request is recorded in Test Logs. Check that generation still works with declined consent, no available ad and Stop.
|
|
31
31
|
|
|
32
32
|
Test ads are nonpayable. Complete the [Live prerequisites](https://wavebird.ai/api/guides/going-live) before requesting Live activation.
|
|
33
33
|
|
|
34
|
-
For Next.js, you can use the [generator](docs/web/nextjs.md) instead of copying Dashboard's route files.
|
|
34
|
+
For Next.js, you can use the [generator](https://github.com/wavebird-ai/api/blob/main/docs/web/nextjs.md) instead of copying Dashboard's route files.
|
|
35
35
|
|
|
36
36
|
## Connect your model output
|
|
37
37
|
|
|
38
38
|
Use `@wavebirdai/api/server` on the server and `@wavebirdai/api/browser` for the ad slot. Your response consumer must display the model output and finish only after the result is visible.
|
|
39
39
|
|
|
40
|
-
[JavaScript and TypeScript examples](docs/web/generation.md) | [Server and browser reference](docs/web/reference.md)
|
|
40
|
+
[JavaScript and TypeScript examples](https://github.com/wavebird-ai/api/blob/main/docs/web/generation.md) | [Server and browser reference](https://github.com/wavebird-ai/api/blob/main/docs/web/reference.md)
|
|
41
|
+
|
|
42
|
+
## Consent appearance
|
|
43
|
+
|
|
44
|
+
The wavebird dialog follows the visitor's browser language. Optional `consentLocale` supplies a fallback before English; `consentTheme` adjusts appearance. Consent choices and permissions stay unchanged. See [consent appearance](https://github.com/wavebird-ai/api/blob/main/docs/web/reference.md#consent-appearance) for supported languages and options.
|
|
41
45
|
|
|
42
46
|
## Update an existing integration
|
|
43
47
|
|
package/dist/browser.d.ts
CHANGED
|
@@ -17,6 +17,18 @@ export type PublisherAds<Bound extends boolean = boolean> = {
|
|
|
17
17
|
deny(): Promise<unknown>;
|
|
18
18
|
withdraw(): Promise<unknown>;
|
|
19
19
|
};
|
|
20
|
+
export type PublisherConsentTheme = {
|
|
21
|
+
/** Six-digit hex colors. Insufficient contrast falls back to readable colors. */
|
|
22
|
+
accentColor?: string;
|
|
23
|
+
backgroundColor?: string;
|
|
24
|
+
textColor?: string;
|
|
25
|
+
/** Font family names only, without CSS rules or URLs. No font is downloaded. */
|
|
26
|
+
fontFamily?: string;
|
|
27
|
+
/** Corner radius in pixels, 0–20. */
|
|
28
|
+
radius?: number;
|
|
29
|
+
/** Card padding in pixels, 12–32. */
|
|
30
|
+
spacing?: number;
|
|
31
|
+
};
|
|
20
32
|
type PublisherAdsOptionsBase = {
|
|
21
33
|
target: HTMLElement;
|
|
22
34
|
clientId: string;
|
|
@@ -26,6 +38,10 @@ type PublisherAdsOptionsBase = {
|
|
|
26
38
|
conversationId: string;
|
|
27
39
|
timing?: "before" | "during" | "after";
|
|
28
40
|
consentMode?: "wavebird_consent" | "own_cmp";
|
|
41
|
+
/** Defaults to browser language preferences, then English. Optional BCP 47 language tag or "auto". */
|
|
42
|
+
consentLocale?: string;
|
|
43
|
+
/** Presentation only. Does not change consent choices or storage. */
|
|
44
|
+
consentTheme?: PublisherConsentTheme;
|
|
29
45
|
/** Optional official renderer URL. Only https://api.wavebird.ai/v1/render.js is supported. */
|
|
30
46
|
rendererUrl?: string;
|
|
31
47
|
privacySettingsTarget?: string;
|
package/dist/browser.js
CHANGED
|
@@ -54,6 +54,23 @@ export function createPublisherAds(options) {
|
|
|
54
54
|
throw new Error("publisher_format_hook_invalid");
|
|
55
55
|
if (options.onDiagnostic !== undefined && typeof options.onDiagnostic !== "function")
|
|
56
56
|
throw new Error("publisher_diagnostic_hook_invalid");
|
|
57
|
+
if (options.consentLocale !== undefined && (typeof options.consentLocale !== "string" ||
|
|
58
|
+
!/^(?:auto|[a-z]{2,3}(?:-[a-z0-9]{2,8})*)$/i.test(options.consentLocale)))
|
|
59
|
+
throw new Error("publisher_consent_locale_invalid");
|
|
60
|
+
const consentTheme = options.consentTheme === undefined ? undefined : options.consentTheme;
|
|
61
|
+
if (consentTheme !== undefined) {
|
|
62
|
+
const validators = {
|
|
63
|
+
accentColor: value => typeof value === "string" && /^#[\da-f]{6}$/i.test(value),
|
|
64
|
+
backgroundColor: value => typeof value === "string" && /^#[\da-f]{6}$/i.test(value),
|
|
65
|
+
textColor: value => typeof value === "string" && /^#[\da-f]{6}$/i.test(value),
|
|
66
|
+
fontFamily: value => typeof value === "string" && /^[a-z0-9 ,"'\-]{1,160}$/i.test(value),
|
|
67
|
+
radius: value => typeof value === "number" && Number.isFinite(value) && value >= 0 && value <= 20,
|
|
68
|
+
spacing: value => typeof value === "number" && Number.isFinite(value) && value >= 12 && value <= 32,
|
|
69
|
+
};
|
|
70
|
+
if (!consentTheme || typeof consentTheme !== "object" || Array.isArray(consentTheme) ||
|
|
71
|
+
Object.entries(consentTheme).some(([key, value]) => !Object.hasOwn(validators, key) || !validators[key](value)))
|
|
72
|
+
throw new Error("publisher_consent_theme_invalid");
|
|
73
|
+
}
|
|
57
74
|
let privacyTarget = null;
|
|
58
75
|
if (consentMode === "wavebird_consent" && options.privacySettingsTarget !== undefined) {
|
|
59
76
|
if (typeof options.privacySettingsTarget !== "string" || !options.privacySettingsTarget.trim())
|
|
@@ -80,7 +97,9 @@ export function createPublisherAds(options) {
|
|
|
80
97
|
// Renderer failures originate in a child mount and do not bubble.
|
|
81
98
|
slot.addEventListener?.("ad:render_failed", onRenderFailure, true);
|
|
82
99
|
slot.setAttribute("aria-label", "Sponsored placement");
|
|
83
|
-
|
|
100
|
+
// The hosted creative clips its own contents. Clipping this full-width mount
|
|
101
|
+
// loses a fractional pixel at some device scales and invalidates visibility.
|
|
102
|
+
slot.style.cssText = "width:100%;height:100%;overflow:visible;margin:0 auto";
|
|
84
103
|
target.append(slot);
|
|
85
104
|
const openPrivacySettings = () => { if (!disposed) sponsor?.openPrivacySettings(); };
|
|
86
105
|
privacyTarget?.addEventListener("click", openPrivacySettings);
|
|
@@ -148,6 +167,8 @@ export function createPublisherAds(options) {
|
|
|
148
167
|
sponsor = window.wavebird.createChatSponsor({ target: slot, ...binding,
|
|
149
168
|
clientId: options.clientId, surfaceId: options.surfaceId, jobType: options.jobType, timing, consentMode,
|
|
150
169
|
cleanupAfterClip: true,
|
|
170
|
+
...(options.consentLocale === undefined ? {} : { consentLocale: options.consentLocale }),
|
|
171
|
+
...(consentTheme === undefined ? {} : { consentTheme: { ...consentTheme } }),
|
|
151
172
|
...(turnBinding ? { turnBinding: true } : {}),
|
|
152
173
|
...(options.getFormat === undefined ? {} : { getFormat: options.getFormat }),
|
|
153
174
|
...(options.placementEndpoint === undefined ? {} : { placementEndpoint: options.placementEndpoint }),
|
package/docs/web/generation.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Connect generation to the displayed result
|
|
2
2
|
|
|
3
|
-
These are connection helpers, not complete apps. Use the same installed `@wavebirdai/api@0.1.0-beta.
|
|
3
|
+
These are connection helpers, not complete apps. Use the same installed `@wavebirdai/api@0.1.0-beta.18` as your server routes.
|
|
4
4
|
|
|
5
5
|
- `ads` is the instance for this surface, returned by `createPublisherAds` or the generated component's `onReady` callback.
|
|
6
6
|
- `sendExistingRequest` sends your existing authenticated model request. Merge the provided headers into its headers and preserve its body and abort signal. Call the route wrapped by `withGeneration`.
|
package/docs/web/nextjs.md
CHANGED
|
@@ -11,7 +11,7 @@ If your app sets Content Security Policy, allow `https://api.wavebird.ai` in its
|
|
|
11
11
|
From the folder containing `package.json`:
|
|
12
12
|
|
|
13
13
|
```sh
|
|
14
|
-
npm install @wavebirdai/api@0.1.0-beta.
|
|
14
|
+
npm install @wavebirdai/api@0.1.0-beta.18 server-only
|
|
15
15
|
./node_modules/.bin/wavebird-next init --lang ts --root . --app-dir src/app
|
|
16
16
|
```
|
|
17
17
|
|
package/docs/web/reference.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Web integration reference
|
|
2
2
|
|
|
3
|
-
Applies to `@wavebirdai/api@0.1.0-beta.
|
|
3
|
+
Applies to `@wavebirdai/api@0.1.0-beta.18`. [Start with the integration steps](../../README.md#set-up-javascript-or-typescript).
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
`@wavebirdai/api/server` exports `createPublisherServer`. Configure it with server-only Project ID, Server Test or production Key, preference signing secret, the publisher's real request authorization function, exact `publicOrigins`, and the saved project/placement values shown in the dashboard. The origin list is required. The package compares the browser Origin with a configured public origin whose host matches the route Host, even when Next.js or a proxy gives the route an internal URL. `localhost` and `127.0.0.1` are separate origins, and each port and scheme must match exactly; HTTP loopback is available only with a Server Test Key. A production key also requires its separately approved project and wavebird server authority. Omit `bidfloor` and `bidfloorCurrency` to inherit saved pricing. An explicit override supplies both a nonnegative amount, including zero, and a three-letter currency; the API validates it against the saved project. It returns authenticated `placementPOST`, `consentGET`, `consentPOST`, and `withGeneration` handlers, plus the server-only `reportGeneration(jobId, event)` method. The helper constructs the existing `/v1/placements`, `/v1/consent`, and `/v1/jobs/{id}/generation/{event}` requests; it does not introduce a new wavebird protocol. The wavebird API remains authoritative for saved scope, creative formats, duration, fallback, and financial classification.
|
|
@@ -30,6 +30,22 @@ For renderer failures, the browser's optional `onDiagnostic` receives only a fix
|
|
|
30
30
|
|
|
31
31
|
Use the existing `generationId` in the server `onLifecycle` observer to correlate generation events. It is not a credential. Retain only that ID, event category and relative timing, never session identities, request headers or response contents. A renderer error without an exact turn or slot link must stay uncorrelated.
|
|
32
32
|
|
|
33
|
+
## Consent appearance
|
|
34
|
+
|
|
35
|
+
The hosted renderer uses the first supported language in the visitor's browser preferences. Optional `consentLocale: "de-DE"` on `createPublisherAds` is a fallback if none matches. English is the final fallback. Omit it or use `"auto"` to keep the English fallback.
|
|
36
|
+
|
|
37
|
+
Supported languages: English, Spanish, German, Japanese, French, Portuguese, Russian, Italian, Dutch, Polish, Turkish, Indonesian, Chinese, Persian, Czech, Vietnamese, Korean, Arabic, Ukrainian and Hungarian. Chinese includes simplified and traditional script. Korean uses South Korean wording. Arabic and Persian use right-to-left text.
|
|
38
|
+
|
|
39
|
+
Language support is delivered by the hosted renderer. Browser preferences take priority over the publisher fallback.
|
|
40
|
+
|
|
41
|
+
The optional `consentTheme` accepts `accentColor`, `backgroundColor` and `textColor` as six-digit hex colors, `fontFamily` as existing font names, `radius` from 0 to 20, and `spacing` from 12 to 32 pixels. Low-contrast colors fall back to readable colors. No fonts are downloaded. For example:
|
|
42
|
+
|
|
43
|
+
```js
|
|
44
|
+
consentTheme: { accentColor: "#243c5a", radius: 4, fontFamily: "Arial, sans-serif" }
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
This is a configuration fragment, not a complete integration. Appearance does not change choices, storage, consent requirements or the `own_cmp` integration. Do not hide, rename or disable consent actions with app styles.
|
|
48
|
+
|
|
33
49
|
## Troubleshooting
|
|
34
50
|
|
|
35
51
|
With the trusted-session integration, consent restoration reads the current server revision before synchronizing the saved choice. Reloading does not reset consent revisions. An unavailable revision keeps ads disabled until consent can be synchronized; it does not block the model response.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wavebirdai/api",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.18",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "JavaScript and TypeScript integration for wavebird Banner, Native and Clip ads, with consent and generation lifecycle handling.",
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"bin",
|
|
21
21
|
"templates",
|
|
22
22
|
"README.md",
|
|
23
|
+
"CHANGELOG.md",
|
|
23
24
|
"LICENSE",
|
|
24
25
|
"docs/web",
|
|
25
26
|
"python/README.md",
|
package/src/browser.d.ts
CHANGED
|
@@ -17,6 +17,18 @@ export type PublisherAds<Bound extends boolean = boolean> = {
|
|
|
17
17
|
deny(): Promise<unknown>;
|
|
18
18
|
withdraw(): Promise<unknown>;
|
|
19
19
|
};
|
|
20
|
+
export type PublisherConsentTheme = {
|
|
21
|
+
/** Six-digit hex colors. Insufficient contrast falls back to readable colors. */
|
|
22
|
+
accentColor?: string;
|
|
23
|
+
backgroundColor?: string;
|
|
24
|
+
textColor?: string;
|
|
25
|
+
/** Font family names only, without CSS rules or URLs. No font is downloaded. */
|
|
26
|
+
fontFamily?: string;
|
|
27
|
+
/** Corner radius in pixels, 0–20. */
|
|
28
|
+
radius?: number;
|
|
29
|
+
/** Card padding in pixels, 12–32. */
|
|
30
|
+
spacing?: number;
|
|
31
|
+
};
|
|
20
32
|
type PublisherAdsOptionsBase = {
|
|
21
33
|
target: HTMLElement;
|
|
22
34
|
clientId: string;
|
|
@@ -26,6 +38,10 @@ type PublisherAdsOptionsBase = {
|
|
|
26
38
|
conversationId: string;
|
|
27
39
|
timing?: "before" | "during" | "after";
|
|
28
40
|
consentMode?: "wavebird_consent" | "own_cmp";
|
|
41
|
+
/** Defaults to browser language preferences, then English. Optional BCP 47 language tag or "auto". */
|
|
42
|
+
consentLocale?: string;
|
|
43
|
+
/** Presentation only. Does not change consent choices or storage. */
|
|
44
|
+
consentTheme?: PublisherConsentTheme;
|
|
29
45
|
/** Optional official renderer URL. Only https://api.wavebird.ai/v1/render.js is supported. */
|
|
30
46
|
rendererUrl?: string;
|
|
31
47
|
privacySettingsTarget?: string;
|
package/src/browser.js
CHANGED
|
@@ -54,6 +54,23 @@ export function createPublisherAds(options) {
|
|
|
54
54
|
throw new Error("publisher_format_hook_invalid");
|
|
55
55
|
if (options.onDiagnostic !== undefined && typeof options.onDiagnostic !== "function")
|
|
56
56
|
throw new Error("publisher_diagnostic_hook_invalid");
|
|
57
|
+
if (options.consentLocale !== undefined && (typeof options.consentLocale !== "string" ||
|
|
58
|
+
!/^(?:auto|[a-z]{2,3}(?:-[a-z0-9]{2,8})*)$/i.test(options.consentLocale)))
|
|
59
|
+
throw new Error("publisher_consent_locale_invalid");
|
|
60
|
+
const consentTheme = options.consentTheme === undefined ? undefined : options.consentTheme;
|
|
61
|
+
if (consentTheme !== undefined) {
|
|
62
|
+
const validators = {
|
|
63
|
+
accentColor: value => typeof value === "string" && /^#[\da-f]{6}$/i.test(value),
|
|
64
|
+
backgroundColor: value => typeof value === "string" && /^#[\da-f]{6}$/i.test(value),
|
|
65
|
+
textColor: value => typeof value === "string" && /^#[\da-f]{6}$/i.test(value),
|
|
66
|
+
fontFamily: value => typeof value === "string" && /^[a-z0-9 ,"'\-]{1,160}$/i.test(value),
|
|
67
|
+
radius: value => typeof value === "number" && Number.isFinite(value) && value >= 0 && value <= 20,
|
|
68
|
+
spacing: value => typeof value === "number" && Number.isFinite(value) && value >= 12 && value <= 32,
|
|
69
|
+
};
|
|
70
|
+
if (!consentTheme || typeof consentTheme !== "object" || Array.isArray(consentTheme) ||
|
|
71
|
+
Object.entries(consentTheme).some(([key, value]) => !Object.hasOwn(validators, key) || !validators[key](value)))
|
|
72
|
+
throw new Error("publisher_consent_theme_invalid");
|
|
73
|
+
}
|
|
57
74
|
let privacyTarget = null;
|
|
58
75
|
if (consentMode === "wavebird_consent" && options.privacySettingsTarget !== undefined) {
|
|
59
76
|
if (typeof options.privacySettingsTarget !== "string" || !options.privacySettingsTarget.trim())
|
|
@@ -80,7 +97,9 @@ export function createPublisherAds(options) {
|
|
|
80
97
|
// Renderer failures originate in a child mount and do not bubble.
|
|
81
98
|
slot.addEventListener?.("ad:render_failed", onRenderFailure, true);
|
|
82
99
|
slot.setAttribute("aria-label", "Sponsored placement");
|
|
83
|
-
|
|
100
|
+
// The hosted creative clips its own contents. Clipping this full-width mount
|
|
101
|
+
// loses a fractional pixel at some device scales and invalidates visibility.
|
|
102
|
+
slot.style.cssText = "width:100%;height:100%;overflow:visible;margin:0 auto";
|
|
84
103
|
target.append(slot);
|
|
85
104
|
const openPrivacySettings = () => { if (!disposed) sponsor?.openPrivacySettings(); };
|
|
86
105
|
privacyTarget?.addEventListener("click", openPrivacySettings);
|
|
@@ -148,6 +167,8 @@ export function createPublisherAds(options) {
|
|
|
148
167
|
sponsor = window.wavebird.createChatSponsor({ target: slot, ...binding,
|
|
149
168
|
clientId: options.clientId, surfaceId: options.surfaceId, jobType: options.jobType, timing, consentMode,
|
|
150
169
|
cleanupAfterClip: true,
|
|
170
|
+
...(options.consentLocale === undefined ? {} : { consentLocale: options.consentLocale }),
|
|
171
|
+
...(consentTheme === undefined ? {} : { consentTheme: { ...consentTheme } }),
|
|
151
172
|
...(turnBinding ? { turnBinding: true } : {}),
|
|
152
173
|
...(options.getFormat === undefined ? {} : { getFormat: options.getFormat }),
|
|
153
174
|
...(options.placementEndpoint === undefined ? {} : { placementEndpoint: options.placementEndpoint }),
|
package/templates/NEXT-SETUP.md
CHANGED
|
@@ -6,7 +6,7 @@ The generator installed `lib/publisher`, `lib/auth`, `lib/turn-store` and `lib/m
|
|
|
6
6
|
|
|
7
7
|
Install `server-only` in your app (`npm install server-only`). Install `pg` too if you use the PostgreSQL adapter. Use the full Server ENV from Dashboard's Integration step 2, including the saved preference secret and origins. A key-only ENV download is not the full configuration. Keep the preference secret unchanged across restarts.
|
|
8
8
|
|
|
9
|
-
1. Copy the complete Server ENV from the Dashboard: `WAVEBIRD_CLIENT_ID`, `WAVEBIRD_SECRET_KEY`, `WAVEBIRD_PREFERENCE_SECRET`, and `WAVEBIRD_PUBLIC_ORIGINS`. Keep the saved preference secret stable. The origins value is a comma-separated list of the exact scheme, host, and port where your app is opened. Keep the Dashboard project domain at your real HTTPS host. For local Server Test-key testing, include the exact loopback origin in `WAVEBIRD_PUBLIC_ORIGINS` without changing that project domain; Browser Test Keys instead use their separate Allowed origins field in API Keys. `localhost` and `127.0.0.1` are distinct. Do not use wildcards. The package rejects an absent or malformed list. Never expose server secrets through `NEXT_PUBLIC_` or client props. `clientId` is the public project ID.
|
|
9
|
+
1. Copy the complete Server ENV from the Dashboard: `WAVEBIRD_API_BASE_URL`, `WAVEBIRD_CLIENT_ID`, `WAVEBIRD_SECRET_KEY`, `WAVEBIRD_PREFERENCE_SECRET`, and `WAVEBIRD_PUBLIC_ORIGINS`. Keep the saved preference secret stable. The origins value is a comma-separated list of the exact scheme, host, and port where your app is opened. Keep the Dashboard project domain at your real HTTPS host. For local Server Test-key testing, include the exact loopback origin in `WAVEBIRD_PUBLIC_ORIGINS` without changing that project domain; Browser Test Keys instead use their separate Allowed origins field in API Keys. `localhost` and `127.0.0.1` are distinct. Do not use wildcards. The package rejects an absent or malformed list. Never expose server secrets through `NEXT_PUBLIC_` or client props. `clientId` is the public project ID.
|
|
10
10
|
2. Replace `lib/publisher`'s example surface, placement, allowed sizes, formats, locale, consent mode, and publisher identity with the **saved Dashboard values**. The responsive example lists 728×90 and 320×50 Banner sizes only to show the size-selection shape. The saved sizes define the normal envelope; optional `maxWidth` and `maxHeight` are advanced caps that only narrow it. Keep `responsiveSizeSelection: true` only when the selected project and placement approve every configured size. Remove any size absent from the saved project before Test traffic. The API enforces its own authority; example values do not create a valid placement.
|
|
11
11
|
3. Connect `lib/auth` to the app's real session authorization. Its supplied path check fails closed when `PUBLISHER_AUTH_CHECK_PATH` is absent. The path must be a publisher-owned same-origin route that returns 204 only for an authorized user and supplies an `x-publisher-session-id` header containing a stable non-credential correlation ID for that authenticated session. Never return a cookie, bearer token or raw credential as that ID. The route must not be any wavebird route. The example sends the session cookie to that check only when the request origin exactly matches `WAVEBIRD_PUBLIC_ORIGINS`; a missing or different origin fails closed. The package checks that the browser's session ID matches this server-validated value before placement or generation.
|
|
12
12
|
4. Replace `lib/turn-store`'s fail-closed stub with `createPostgresTurnStorage(yourExistingPgPool)` or another persistent store implementing the package's atomic interface. For PostgreSQL, run the adapter's `install()` once in your normal database migration step; use a pool shared by the publisher's workers. Keep `WAVEBIRD_PREFERENCE_SECRET` stable across workers and restarts; the package derives a separate journal key from it and rejects a changed key for an active project. Coordinate secret rotation after active turns are drained; never clear the journal guard to restore ad service while turns remain. The package owns turn claims, ordered reports, retry and bounded reconciliation. An unavailable store suppresses ad placement while the authenticated model route remains available.
|