@magicfeedback/popup-sdk 1.0.11 → 1.0.12
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/README.md +269 -207
- package/dist/index.d.mts +41 -10
- package/dist/index.d.ts +41 -10
- package/dist/index.js +406 -144
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +406 -144
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
# MagicFeedback Popup SDK
|
|
2
2
|
|
|
3
|
-
TypeScript SDK
|
|
3
|
+
TypeScript SDK for loading and displaying MagicFeedback surveys as popups in browser apps.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Package name: `@magicfeedback/popup-sdk`
|
|
6
|
+
|
|
7
|
+
## What It Does
|
|
8
|
+
|
|
9
|
+
- Loads popup definitions from the Deepdots API (`server` mode) or from inline definitions (`client` mode)
|
|
10
|
+
- Triggers popups by time on page, scroll depth, click, route exit, or host-driven events
|
|
11
|
+
- Emits lifecycle events so the host app can track popup activity
|
|
12
|
+
- Supports route targeting through `segments.path`
|
|
13
|
+
- Falls back to a no-op renderer outside the browser
|
|
6
14
|
|
|
7
15
|
## Installation
|
|
8
16
|
|
|
@@ -10,185 +18,300 @@ TypeScript SDK to render and manage survey popups for MagicFeedback.
|
|
|
10
18
|
npm install @magicfeedback/popup-sdk
|
|
11
19
|
```
|
|
12
20
|
|
|
13
|
-
##
|
|
21
|
+
## Recommended Setup
|
|
22
|
+
|
|
23
|
+
`server` mode is the recommended setup for real client integrations. Popup definitions are managed remotely and the SDK fetches them at runtime.
|
|
14
24
|
|
|
15
|
-
```
|
|
16
|
-
import {DeepdotsPopups} from '@magicfeedback/popup-sdk';
|
|
25
|
+
```ts
|
|
26
|
+
import { DeepdotsPopups } from '@magicfeedback/popup-sdk';
|
|
17
27
|
|
|
18
|
-
// Basic initialization
|
|
19
28
|
const popups = new DeepdotsPopups();
|
|
29
|
+
|
|
20
30
|
popups.init({
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
productId: 'product-xyz',
|
|
35
|
-
style: {theme: 'light', position: 'bottom-right', imageUrl: null},
|
|
36
|
-
segments: {lang: ['en'], path: ['/checkout']}
|
|
37
|
-
}
|
|
38
|
-
]
|
|
31
|
+
mode: 'server',
|
|
32
|
+
nodeEnv: 'production',
|
|
33
|
+
apiKey: 'YOUR_PUBLIC_API_KEY',
|
|
34
|
+
userId: 'customer-123',
|
|
35
|
+
debug: false,
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
popups.on('popup_shown', (event) => {
|
|
39
|
+
console.log('Popup shown', event);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
popups.on('survey_completed', (event) => {
|
|
43
|
+
console.log('Survey completed', event);
|
|
39
44
|
});
|
|
40
45
|
|
|
41
|
-
// Start triggers
|
|
42
46
|
popups.autoLaunch();
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Notes:
|
|
50
|
+
|
|
51
|
+
- `mode: 'server'` fetches popup definitions from Deepdots.
|
|
52
|
+
- `nodeEnv: 'production'` uses `https://api.deepdots.com`.
|
|
53
|
+
- `nodeEnv: 'development'` uses `https://api-dev.deepdots.com`.
|
|
54
|
+
- `userId` is optional, but recommended when popups are targeted per user.
|
|
55
|
+
- `autoLaunch()` can be called immediately after `init()`. In `server` mode, the SDK waits until remote popups are loaded.
|
|
56
|
+
|
|
57
|
+
## When To Use Each Mode
|
|
58
|
+
|
|
59
|
+
- `server`: production integrations where popup definitions are managed remotely.
|
|
60
|
+
- `client`: local demos, QA, hardcoded fallback flows, and integration testing without API calls.
|
|
61
|
+
|
|
62
|
+
## Real Use Cases From `examples/`
|
|
63
|
+
|
|
64
|
+
### 1. Remote website integration
|
|
65
|
+
|
|
66
|
+
Files:
|
|
67
|
+
|
|
68
|
+
- `examples/index.html`
|
|
69
|
+
- `examples/product.html`
|
|
70
|
+
- `examples/demo-sdk.js`
|
|
71
|
+
|
|
72
|
+
This flow initializes the SDK in `server` mode, auto-launches popups on page load, and logs popup events in the page UI. It is the closest example to a standard website integration.
|
|
73
|
+
|
|
74
|
+
### 2. Host-driven business event trigger
|
|
75
|
+
|
|
76
|
+
Files:
|
|
77
|
+
|
|
78
|
+
- `examples/clients/casino/sdk.js`
|
|
79
|
+
- `examples/clients/casino/sdk-trigger-event-example.js`
|
|
80
|
+
|
|
81
|
+
This flow tracks search behavior in the host app and calls:
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
sdk.triggerEvent('search');
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Use this pattern when popup logic depends on product behavior instead of plain DOM triggers. In the casino demo, the popup is shown after repeated searches with low intent signals.
|
|
88
|
+
|
|
89
|
+
### 3. Route-exit popup after navigation
|
|
90
|
+
|
|
91
|
+
Files:
|
|
92
|
+
|
|
93
|
+
- `examples/index.html`
|
|
94
|
+
- `examples/product.html`
|
|
95
|
+
|
|
96
|
+
Exit triggers are queued when the user leaves a matching route and rendered on the next route after the configured delay. This is useful for "before you go" feedback flows that should appear after navigation, not before it.
|
|
97
|
+
|
|
98
|
+
### 4. Inline client-mode sandbox
|
|
99
|
+
|
|
100
|
+
File:
|
|
101
|
+
|
|
102
|
+
- `examples/demo.html`
|
|
103
|
+
|
|
104
|
+
This example uses local popup definitions and is useful for validating trigger behavior without hitting the API.
|
|
105
|
+
|
|
106
|
+
## Client Mode Example
|
|
107
|
+
|
|
108
|
+
Use `client` mode when you want to preload popup definitions yourself.
|
|
109
|
+
|
|
110
|
+
```ts
|
|
111
|
+
import { DeepdotsPopups } from '@magicfeedback/popup-sdk';
|
|
112
|
+
|
|
113
|
+
const popupDefinitions = [
|
|
114
|
+
{
|
|
115
|
+
id: 'popup-home-5s',
|
|
116
|
+
title: 'Help us improve',
|
|
117
|
+
message: '<p>Thanks for visiting our homepage.</p>',
|
|
118
|
+
triggers: [
|
|
119
|
+
{ type: 'time_on_page', value: 5 },
|
|
120
|
+
],
|
|
121
|
+
cooldown: [
|
|
122
|
+
{ answered: 'SHOWED', cooldownDays: 7 },
|
|
123
|
+
{ answered: 'COMPLETED', cooldownDays: 30 },
|
|
124
|
+
],
|
|
125
|
+
actions: {
|
|
126
|
+
accept: {
|
|
127
|
+
label: 'Open survey',
|
|
128
|
+
surveyId: 'survey-home-001',
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
surveyId: 'survey-home-001',
|
|
132
|
+
productId: 'product-main',
|
|
133
|
+
segments: {
|
|
134
|
+
path: ['/', '/pricing', '/#/home'],
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
];
|
|
138
|
+
|
|
139
|
+
const popups = new DeepdotsPopups();
|
|
43
140
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
popups
|
|
141
|
+
popups.init({
|
|
142
|
+
mode: 'client',
|
|
143
|
+
debug: true,
|
|
144
|
+
popups: popupDefinitions,
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
popups.autoLaunch();
|
|
48
148
|
```
|
|
49
149
|
|
|
50
|
-
|
|
150
|
+
Important:
|
|
51
151
|
|
|
52
|
-
-
|
|
53
|
-
-
|
|
54
|
-
-
|
|
55
|
-
- ✅ Conditions & cooldowns: prevent display if already answered or within cooldown window
|
|
56
|
-
- ✅ Event system: `popup_shown`, `popup_clicked`, `survey_completed`
|
|
57
|
-
- ✅ Renderer abstraction: browser, React Native stub, SSR-friendly no-op
|
|
58
|
-
- ✅ TypeScript: full type definitions
|
|
59
|
-
- ✅ Lightweight: zero runtime dependencies for core logic
|
|
60
|
-
- ✅ Framework agnostic: works in vanilla JS or any framework
|
|
152
|
+
- The property name is `triggers`, and it is now an array.
|
|
153
|
+
- `time_on_page` values are defined in seconds.
|
|
154
|
+
- `segments.path` can contain full URLs, path fragments such as `/pricing`, or hash routes such as `/#/home`.
|
|
61
155
|
|
|
62
|
-
## API
|
|
156
|
+
## API Essentials
|
|
63
157
|
|
|
64
|
-
###
|
|
65
|
-
Main class for configuring and displaying survey popups.
|
|
158
|
+
### `init(config)`
|
|
66
159
|
|
|
67
|
-
|
|
68
|
-
Initializes the SDK. Must be called before other methods.
|
|
160
|
+
Initializes the SDK.
|
|
69
161
|
|
|
70
|
-
```
|
|
162
|
+
```ts
|
|
71
163
|
popups.init({
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
164
|
+
mode: 'server',
|
|
165
|
+
apiKey: 'YOUR_PUBLIC_API_KEY',
|
|
166
|
+
userId: 'customer-123',
|
|
167
|
+
nodeEnv: 'production',
|
|
168
|
+
debug: false,
|
|
77
169
|
});
|
|
78
170
|
```
|
|
79
171
|
|
|
80
|
-
|
|
172
|
+
Config fields:
|
|
81
173
|
|
|
82
|
-
|
|
83
|
-
|
|
174
|
+
- `apiKey?: string`
|
|
175
|
+
- `userId?: string`
|
|
176
|
+
- `nodeEnv?: 'development' | 'production'`
|
|
177
|
+
- `mode?: 'server' | 'client'`
|
|
178
|
+
- `debug?: boolean`
|
|
179
|
+
- `popups?: PopupDefinition[]`
|
|
84
180
|
|
|
85
|
-
|
|
86
|
-
|
|
181
|
+
### `autoLaunch()`
|
|
182
|
+
|
|
183
|
+
Starts the triggers derived from the popup definitions loaded during `init()`.
|
|
184
|
+
|
|
185
|
+
```ts
|
|
186
|
+
popups.autoLaunch();
|
|
87
187
|
```
|
|
88
188
|
|
|
89
|
-
|
|
90
|
-
Displays a popup using its definition `id` (internally maps to `surveyId` + `productId`).
|
|
189
|
+
### `triggerEvent(eventName)`
|
|
91
190
|
|
|
92
|
-
|
|
93
|
-
|
|
191
|
+
Shows the first eligible popup whose definition contains:
|
|
192
|
+
|
|
193
|
+
```ts
|
|
194
|
+
triggers: [{ type: 'event', value: eventName }]
|
|
94
195
|
```
|
|
95
196
|
|
|
96
|
-
|
|
97
|
-
Registers manual triggers. Most apps should use `autoLaunch()` and popup definitions instead.
|
|
197
|
+
Example:
|
|
98
198
|
|
|
99
|
-
```
|
|
100
|
-
popups.
|
|
101
|
-
{ type: 'time', value: 5000, surveyId: 'survey-1' },
|
|
102
|
-
{ type: 'scroll', value: 60, surveyId: 'survey-2' },
|
|
103
|
-
{ type: 'exit', surveyId: 'survey-3' },
|
|
104
|
-
{ type: 'click', value: 'cta-button', surveyId: 'survey-4' }
|
|
105
|
-
]);
|
|
199
|
+
```ts
|
|
200
|
+
popups.triggerEvent('search');
|
|
106
201
|
```
|
|
107
202
|
|
|
108
|
-
|
|
109
|
-
Starts automatic trigger evaluation. If popups are not yet loaded (server mode) call is deferred until load completes.
|
|
203
|
+
### `show({ surveyId, productId })`
|
|
110
204
|
|
|
111
|
-
|
|
112
|
-
|
|
205
|
+
Shows a popup immediately without waiting for a trigger.
|
|
206
|
+
|
|
207
|
+
```ts
|
|
208
|
+
popups.show({
|
|
209
|
+
surveyId: 'survey-home-001',
|
|
210
|
+
productId: 'product-main',
|
|
211
|
+
});
|
|
113
212
|
```
|
|
114
213
|
|
|
115
|
-
|
|
116
|
-
Evaluates conditions and, if allowed, shows a popup for the specified survey. Used internally by trigger handlers; you normally don’t call this directly.
|
|
214
|
+
### `showByPopupId(popupId)`
|
|
117
215
|
|
|
118
|
-
|
|
119
|
-
Marks a survey as answered to satisfy conditions like `{ answered: false }`.
|
|
216
|
+
Shows a popup definition by id. This is useful when multiple popups reuse the same `surveyId`.
|
|
120
217
|
|
|
121
|
-
```
|
|
122
|
-
popups.
|
|
218
|
+
```ts
|
|
219
|
+
popups.showByPopupId('popup-home-5s');
|
|
123
220
|
```
|
|
124
221
|
|
|
125
|
-
|
|
126
|
-
|
|
222
|
+
### `markSurveyAnswered(surveyId)`
|
|
223
|
+
|
|
224
|
+
Marks a survey as answered so cooldown rules like `{ answered: 'COMPLETED', cooldownDays: 30 }` start applying.
|
|
127
225
|
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
popups.on('popup_shown', handler);
|
|
131
|
-
popups.off('popup_shown', handler);
|
|
226
|
+
```ts
|
|
227
|
+
popups.markSurveyAnswered('survey-home-001');
|
|
132
228
|
```
|
|
133
229
|
|
|
134
|
-
|
|
135
|
-
|
|
230
|
+
### `on(eventType, listener)` / `off(eventType, listener)`
|
|
231
|
+
|
|
232
|
+
Subscribe or unsubscribe from SDK events.
|
|
233
|
+
|
|
234
|
+
```ts
|
|
235
|
+
const onShown = (event) => console.log(event);
|
|
136
236
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
const sdk = new DeepdotsPopups();
|
|
140
|
-
sdk.setRenderer(new ReactNativePopupRenderer());
|
|
141
|
-
sdk.init({ mode: 'client', popups: [...] });
|
|
237
|
+
popups.on('popup_shown', onShown);
|
|
238
|
+
popups.off('popup_shown', onShown);
|
|
142
239
|
```
|
|
143
240
|
|
|
144
|
-
##
|
|
241
|
+
## Supported Trigger Types
|
|
145
242
|
|
|
146
|
-
|
|
147
|
-
- `time_on_page` (seconds) → mapped automatically to internal `time` trigger (milliseconds)
|
|
148
|
-
- `scroll` (percentage scrolled)
|
|
149
|
-
- `exit` (route/navigation exit intent)
|
|
150
|
-
- `click` (element id, string)
|
|
243
|
+
Popup definitions use these trigger types:
|
|
151
244
|
|
|
152
|
-
|
|
245
|
+
- `time_on_page`: shows after N seconds on the page
|
|
246
|
+
- `scroll`: shows after reaching a scroll percentage
|
|
247
|
+
- `click`: shows after clicking the element with the given DOM id
|
|
248
|
+
- `exit`: shows after leaving a matching route and waiting N seconds on the destination route
|
|
249
|
+
- `event`: shows when the host app calls `triggerEvent(name)`
|
|
153
250
|
|
|
154
|
-
|
|
251
|
+
## Popup Definition Shape
|
|
252
|
+
|
|
253
|
+
`client` mode accepts popup definitions with this structure:
|
|
254
|
+
|
|
255
|
+
```ts
|
|
155
256
|
interface PopupDefinition {
|
|
156
257
|
id: string;
|
|
157
258
|
title: string;
|
|
158
|
-
message: string;
|
|
159
|
-
triggers: {
|
|
160
|
-
type: 'time_on_page' | 'scroll' | 'exit' | 'click';
|
|
161
|
-
value: number | string;
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
259
|
+
message: string;
|
|
260
|
+
triggers: Array<{
|
|
261
|
+
type: 'time_on_page' | 'scroll' | 'exit' | 'click' | 'event';
|
|
262
|
+
value: number | string;
|
|
263
|
+
}>;
|
|
264
|
+
cooldown?: Array<{
|
|
265
|
+
answered: 'SHOWED' | 'PARTIAL' | 'COMPLETED';
|
|
266
|
+
cooldownDays: number;
|
|
267
|
+
}>;
|
|
268
|
+
actions?: {
|
|
269
|
+
accept?: {
|
|
270
|
+
label: string;
|
|
271
|
+
surveyId: string;
|
|
272
|
+
};
|
|
273
|
+
start?: {
|
|
274
|
+
label: string;
|
|
275
|
+
};
|
|
276
|
+
back?: {
|
|
277
|
+
label: string;
|
|
278
|
+
};
|
|
279
|
+
complete?: {
|
|
280
|
+
label: string;
|
|
281
|
+
surveyId: string;
|
|
282
|
+
autoCompleteParams: Record<string, unknown>;
|
|
283
|
+
cooldownDays?: number;
|
|
284
|
+
};
|
|
285
|
+
decline?: {
|
|
286
|
+
label: string;
|
|
287
|
+
cooldownDays?: number;
|
|
288
|
+
};
|
|
167
289
|
};
|
|
168
290
|
surveyId: string;
|
|
169
291
|
productId: string;
|
|
170
|
-
style
|
|
292
|
+
style?: {
|
|
171
293
|
theme: 'light' | 'dark';
|
|
172
294
|
position: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left' | 'center';
|
|
173
295
|
imageUrl: string | null;
|
|
174
296
|
};
|
|
175
|
-
segments?: {
|
|
297
|
+
segments?: {
|
|
298
|
+
path?: string[];
|
|
299
|
+
[key: string]: unknown;
|
|
300
|
+
};
|
|
176
301
|
}
|
|
177
302
|
```
|
|
178
303
|
|
|
179
|
-
### Conditions
|
|
180
|
-
- `answered: false` → show only if survey not yet completed
|
|
181
|
-
- `cooldownDays: N` → do not show again until N days have passed since last display (per popup definition `id`)
|
|
182
|
-
|
|
183
304
|
## Events
|
|
184
305
|
|
|
185
|
-
|
|
306
|
+
The SDK emits:
|
|
307
|
+
|
|
186
308
|
- `popup_shown`
|
|
187
|
-
- `popup_clicked`
|
|
309
|
+
- `popup_clicked`
|
|
188
310
|
- `survey_completed`
|
|
189
311
|
|
|
190
312
|
Payload:
|
|
191
|
-
|
|
313
|
+
|
|
314
|
+
```ts
|
|
192
315
|
interface DeepdotsEvent {
|
|
193
316
|
type: 'popup_shown' | 'popup_clicked' | 'survey_completed';
|
|
194
317
|
surveyId: string;
|
|
@@ -197,111 +320,50 @@ interface DeepdotsEvent {
|
|
|
197
320
|
}
|
|
198
321
|
```
|
|
199
322
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
```typescript
|
|
203
|
-
{ type: 'time', value: 5000, surveyId: 'survey-1' } // after 5s
|
|
204
|
-
{ type: 'scroll', value: 50, surveyId: 'survey-2' } // at 50% scroll
|
|
205
|
-
{ type: 'exit', surveyId: 'survey-3' } // navigation exit intent
|
|
206
|
-
{ type: 'click', value: 'cta-button', surveyId: 'survey-4' } // click on element id
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
## Automatic Trigger Derivation
|
|
210
|
-
When definitions are loaded, each `time_on_page` trigger is converted to `{ type: 'time', value: seconds * 1000 }`. You just call `autoLaunch()` and derived triggers start.
|
|
211
|
-
|
|
212
|
-
## Trigger Behavior Notes
|
|
213
|
-
- `exit` fires on navigation intent (link clicks or SPA route changes). It does not depend on mouse leaving the viewport.
|
|
214
|
-
- `click` expects a DOM element id in `value`. The handler attaches on `DOMContentLoaded` if the element isn't available immediately.
|
|
323
|
+
`data` often contains values such as:
|
|
215
324
|
|
|
216
|
-
|
|
217
|
-
|
|
325
|
+
- `popupId`
|
|
326
|
+
- `action`
|
|
327
|
+
- `userId`
|
|
218
328
|
|
|
219
|
-
|
|
329
|
+
`popup_clicked` is a general interaction event. Depending on the flow, `data.action` can contain values such as `loaded`, `start_survey`, `manual_send`, `back`, `complete`, or `close_icon`.
|
|
220
330
|
|
|
221
|
-
|
|
331
|
+
## Important Behavior Notes
|
|
222
332
|
|
|
223
|
-
- `
|
|
224
|
-
- `
|
|
225
|
-
- `
|
|
333
|
+
- `segments.path` is the only segment currently evaluated by the SDK runtime.
|
|
334
|
+
- `exit` triggers work across anchor navigation, hash navigation, `history.pushState()`, and `history.replaceState()`.
|
|
335
|
+
- Pending `exit` popups are stored in `sessionStorage` until they are shown or discarded.
|
|
336
|
+
- The default browser renderer uses MagicFeedback forms and applies button labels from `actions.accept`, `actions.start`, `actions.back`, and `actions.complete`.
|
|
337
|
+
- `title`, `message`, and `style` belong to the popup definition contract, but the current browser renderer focuses on the embedded form and does not render those fields as standalone popup copy/layout controls.
|
|
338
|
+
- `actions.decline` is accepted in the definition shape, but the current browser renderer does not render a dedicated decline button or enforce `decline.cooldownDays`.
|
|
339
|
+
- In browser mode, the SDK creates `#deepdots-popup-container` and injects the shared popup stylesheet from jsDelivr.
|
|
226
340
|
|
|
227
|
-
|
|
341
|
+
## Running The Examples Locally
|
|
228
342
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
show(surveyId, productId, data, emit, onClose) {
|
|
234
|
-
// 1. Display native modal
|
|
235
|
-
// 2. Render equivalent UI
|
|
236
|
-
// 3. Call emit('popup_clicked', surveyId, data) on first interaction
|
|
237
|
-
}
|
|
238
|
-
hide() { /* close modal */ }
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
const sdk = new DeepdotsPopups();
|
|
242
|
-
sdk.setRenderer(new MyNativeRenderer());
|
|
243
|
-
sdk.init({ mode: 'client', popups: [...] });
|
|
343
|
+
```bash
|
|
344
|
+
npm install
|
|
345
|
+
npm run build
|
|
346
|
+
python3 -m http.server 4173
|
|
244
347
|
```
|
|
245
348
|
|
|
246
|
-
|
|
247
|
-
1. Build the bundle: `npm run build`.
|
|
248
|
-
2. Load `dist/` in a WebView.
|
|
249
|
-
3. Bridge events: `window.ReactNativeWebView.postMessage(JSON.stringify(ev))`.
|
|
250
|
-
4. Initialize: `popups.init({...}); popups.autoLaunch();`.
|
|
349
|
+
Then open:
|
|
251
350
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
}
|
|
257
|
-
popups.on('popup_shown', forward);
|
|
258
|
-
popups.on('survey_completed', forward);
|
|
259
|
-
```
|
|
351
|
+
- `http://localhost:4173/examples/index.html`
|
|
352
|
+
- `http://localhost:4173/examples/product.html`
|
|
353
|
+
- `http://localhost:4173/examples/demo.html`
|
|
354
|
+
- `http://localhost:4173/examples/clients/casino/index.html`
|
|
260
355
|
|
|
261
|
-
|
|
262
|
-
Import types directly:
|
|
263
|
-
|
|
264
|
-
```typescript
|
|
265
|
-
import type {
|
|
266
|
-
DeepdotsConfig,
|
|
267
|
-
TriggerConfig,
|
|
268
|
-
ShowOptions,
|
|
269
|
-
DeepdotsEvent,
|
|
270
|
-
DeepdotsEventType,
|
|
271
|
-
EventListener,
|
|
272
|
-
} from '@magicfeedback/popup-sdk';
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
## Example Demo
|
|
276
|
-
See `examples/demo.html` for a runnable browser demo (uses client mode + fake definitions). To try it:
|
|
277
|
-
1. Build the project (`npm run build`).
|
|
278
|
-
2. Open `examples/demo.html` in a browser.
|
|
279
|
-
3. Use buttons to show popups and observe console + event log.
|
|
356
|
+
Using a local HTTP server is recommended. Some browser module imports and navigation flows do not behave correctly when opening the files directly with `file://`.
|
|
280
357
|
|
|
281
358
|
## Development
|
|
282
359
|
|
|
283
360
|
```bash
|
|
284
|
-
npm
|
|
285
|
-
npm run build
|
|
286
|
-
npm run
|
|
287
|
-
npm
|
|
288
|
-
npm test # run vitest
|
|
289
|
-
npm run test:watch # watch tests
|
|
361
|
+
npm run build
|
|
362
|
+
npm run build:watch
|
|
363
|
+
npm run lint
|
|
364
|
+
npm test
|
|
290
365
|
```
|
|
291
366
|
|
|
292
|
-
Publishing uses `prepublishOnly` to ensure a fresh build.
|
|
293
|
-
|
|
294
|
-
## Notes & Limitations
|
|
295
|
-
- `server` mode currently simulates fetch; real network integration pending.
|
|
296
|
-
- `apiKey` is reserved for future authenticated endpoints.
|
|
297
|
-
- React Native renderer provided is a stub (example only).
|
|
298
|
-
- Sanitization of `message` HTML should be handled upstream if untrusted.
|
|
299
|
-
|
|
300
|
-
## Contributing
|
|
301
|
-
Issues & PRs welcome: https://github.com/MagicFeedback/deepdots-popup-sdk
|
|
302
|
-
|
|
303
367
|
## License
|
|
304
|
-
MIT
|
|
305
368
|
|
|
306
|
-
|
|
307
|
-
Open issues on the GitHub repository or contact maintainers.
|
|
369
|
+
MIT
|