@magicfeedback/popup-sdk 1.0.10 → 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 -204
- package/dist/index.d.mts +56 -18
- package/dist/index.d.ts +56 -18
- package/dist/index.js +574 -88
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +574 -88
- 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,187 +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
|
-
title: 'Help us improve?',
|
|
27
|
-
message: '<p>Take a quick survey and share your thoughts.</p>',
|
|
28
|
-
trigger: {type: 'time_on_page', value: 5, condition: [{answered: false, cooldownDays: 7}]},
|
|
29
|
-
actions: {
|
|
30
|
-
accept: {label: 'Take Survey', surveyId: 'survey-abc'},
|
|
31
|
-
decline: {label: 'Not Now', cooldownDays: 7}
|
|
32
|
-
},
|
|
33
|
-
surveyId: 'survey-abc',
|
|
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,
|
|
39
36
|
});
|
|
40
37
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
surveyId: 'survey-abc',
|
|
44
|
-
productId: 'product-xyz',
|
|
45
|
-
data: {source: 'homepage'}
|
|
38
|
+
popups.on('popup_shown', (event) => {
|
|
39
|
+
console.log('Popup shown', event);
|
|
46
40
|
});
|
|
47
41
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
42
|
+
popups.on('survey_completed', (event) => {
|
|
43
|
+
console.log('Survey completed', event);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
popups.autoLaunch();
|
|
52
47
|
```
|
|
53
48
|
|
|
54
|
-
|
|
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
|
|
55
58
|
|
|
56
|
-
-
|
|
57
|
-
-
|
|
58
|
-
- ✅ Automatic trigger derivation from popup definitions (`time_on_page` → internal `time` in ms)
|
|
59
|
-
- ✅ Conditions & cooldowns: prevent display if already answered or within cooldown window
|
|
60
|
-
- ✅ Event system: `popup_shown`, `popup_clicked`, `survey_completed`
|
|
61
|
-
- ✅ Renderer abstraction: browser, React Native stub, SSR-friendly no-op
|
|
62
|
-
- ✅ TypeScript: full type definitions
|
|
63
|
-
- ✅ Lightweight: zero runtime dependencies for core logic
|
|
64
|
-
- ✅ Framework agnostic: works in vanilla JS or any framework
|
|
59
|
+
- `server`: production integrations where popup definitions are managed remotely.
|
|
60
|
+
- `client`: local demos, QA, hardcoded fallback flows, and integration testing without API calls.
|
|
65
61
|
|
|
66
|
-
##
|
|
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
|
+
```
|
|
67
86
|
|
|
68
|
-
|
|
69
|
-
Main class for configuring and displaying survey popups.
|
|
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.
|
|
70
88
|
|
|
71
|
-
|
|
72
|
-
|
|
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();
|
|
73
140
|
|
|
74
|
-
```typescript
|
|
75
141
|
popups.init({
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
debug: false, // verbose logging
|
|
80
|
-
popups: [ /* PopupDefinition[] (client mode only) */ ]
|
|
142
|
+
mode: 'client',
|
|
143
|
+
debug: true,
|
|
144
|
+
popups: popupDefinitions,
|
|
81
145
|
});
|
|
146
|
+
|
|
147
|
+
popups.autoLaunch();
|
|
82
148
|
```
|
|
83
149
|
|
|
84
|
-
|
|
150
|
+
Important:
|
|
85
151
|
|
|
86
|
-
|
|
87
|
-
|
|
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`.
|
|
88
155
|
|
|
89
|
-
|
|
90
|
-
|
|
156
|
+
## API Essentials
|
|
157
|
+
|
|
158
|
+
### `init(config)`
|
|
159
|
+
|
|
160
|
+
Initializes the SDK.
|
|
161
|
+
|
|
162
|
+
```ts
|
|
163
|
+
popups.init({
|
|
164
|
+
mode: 'server',
|
|
165
|
+
apiKey: 'YOUR_PUBLIC_API_KEY',
|
|
166
|
+
userId: 'customer-123',
|
|
167
|
+
nodeEnv: 'production',
|
|
168
|
+
debug: false,
|
|
169
|
+
});
|
|
91
170
|
```
|
|
92
171
|
|
|
93
|
-
|
|
94
|
-
|
|
172
|
+
Config fields:
|
|
173
|
+
|
|
174
|
+
- `apiKey?: string`
|
|
175
|
+
- `userId?: string`
|
|
176
|
+
- `nodeEnv?: 'development' | 'production'`
|
|
177
|
+
- `mode?: 'server' | 'client'`
|
|
178
|
+
- `debug?: boolean`
|
|
179
|
+
- `popups?: PopupDefinition[]`
|
|
180
|
+
|
|
181
|
+
### `autoLaunch()`
|
|
95
182
|
|
|
96
|
-
|
|
97
|
-
|
|
183
|
+
Starts the triggers derived from the popup definitions loaded during `init()`.
|
|
184
|
+
|
|
185
|
+
```ts
|
|
186
|
+
popups.autoLaunch();
|
|
98
187
|
```
|
|
99
188
|
|
|
100
|
-
|
|
101
|
-
Registers manual triggers.
|
|
189
|
+
### `triggerEvent(eventName)`
|
|
102
190
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
{ type: 'exit', surveyId: 'survey-3' }
|
|
108
|
-
]);
|
|
191
|
+
Shows the first eligible popup whose definition contains:
|
|
192
|
+
|
|
193
|
+
```ts
|
|
194
|
+
triggers: [{ type: 'event', value: eventName }]
|
|
109
195
|
```
|
|
110
196
|
|
|
111
|
-
|
|
112
|
-
Starts automatic trigger evaluation. If popups are not yet loaded (server mode) call is deferred until load completes.
|
|
197
|
+
Example:
|
|
113
198
|
|
|
114
|
-
```
|
|
115
|
-
popups.
|
|
199
|
+
```ts
|
|
200
|
+
popups.triggerEvent('search');
|
|
116
201
|
```
|
|
117
202
|
|
|
118
|
-
|
|
119
|
-
Evaluates conditions and, if allowed, shows a popup for the specified survey. Used internally by trigger handlers; you normally don’t call this directly.
|
|
203
|
+
### `show({ surveyId, productId })`
|
|
120
204
|
|
|
121
|
-
|
|
122
|
-
Marks a survey as answered to satisfy conditions like `{ answered: false }`.
|
|
205
|
+
Shows a popup immediately without waiting for a trigger.
|
|
123
206
|
|
|
124
|
-
```
|
|
125
|
-
popups.
|
|
207
|
+
```ts
|
|
208
|
+
popups.show({
|
|
209
|
+
surveyId: 'survey-home-001',
|
|
210
|
+
productId: 'product-main',
|
|
211
|
+
});
|
|
126
212
|
```
|
|
127
213
|
|
|
128
|
-
|
|
129
|
-
|
|
214
|
+
### `showByPopupId(popupId)`
|
|
215
|
+
|
|
216
|
+
Shows a popup definition by id. This is useful when multiple popups reuse the same `surveyId`.
|
|
130
217
|
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
popups.on('popup_shown', handler);
|
|
134
|
-
popups.off('popup_shown', handler);
|
|
218
|
+
```ts
|
|
219
|
+
popups.showByPopupId('popup-home-5s');
|
|
135
220
|
```
|
|
136
221
|
|
|
137
|
-
|
|
138
|
-
Inject a custom renderer (e.g. native mobile). If called after `init` and the renderer has `init()`, it's invoked automatically.
|
|
222
|
+
### `markSurveyAnswered(surveyId)`
|
|
139
223
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
sdk.init({ mode: 'client', popups: [...] });
|
|
224
|
+
Marks a survey as answered so cooldown rules like `{ answered: 'COMPLETED', cooldownDays: 30 }` start applying.
|
|
225
|
+
|
|
226
|
+
```ts
|
|
227
|
+
popups.markSurveyAnswered('survey-home-001');
|
|
145
228
|
```
|
|
146
229
|
|
|
147
|
-
|
|
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);
|
|
236
|
+
|
|
237
|
+
popups.on('popup_shown', onShown);
|
|
238
|
+
popups.off('popup_shown', onShown);
|
|
239
|
+
```
|
|
148
240
|
|
|
149
|
-
|
|
150
|
-
- `time_on_page` (seconds) → mapped automatically to internal `time` trigger (milliseconds)
|
|
151
|
-
- `scroll` (percentage scrolled)
|
|
152
|
-
- `exit` (exit intent)
|
|
241
|
+
## Supported Trigger Types
|
|
153
242
|
|
|
154
|
-
|
|
243
|
+
Popup definitions use these trigger types:
|
|
155
244
|
|
|
156
|
-
|
|
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)`
|
|
250
|
+
|
|
251
|
+
## Popup Definition Shape
|
|
252
|
+
|
|
253
|
+
`client` mode accepts popup definitions with this structure:
|
|
254
|
+
|
|
255
|
+
```ts
|
|
157
256
|
interface PopupDefinition {
|
|
158
257
|
id: string;
|
|
159
258
|
title: string;
|
|
160
|
-
message: string;
|
|
161
|
-
|
|
162
|
-
type: 'time_on_page' | 'scroll' | 'exit';
|
|
163
|
-
value: number
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
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
|
+
};
|
|
169
289
|
};
|
|
170
290
|
surveyId: string;
|
|
171
291
|
productId: string;
|
|
172
|
-
style
|
|
292
|
+
style?: {
|
|
173
293
|
theme: 'light' | 'dark';
|
|
174
294
|
position: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left' | 'center';
|
|
175
295
|
imageUrl: string | null;
|
|
176
296
|
};
|
|
177
|
-
segments?: {
|
|
297
|
+
segments?: {
|
|
298
|
+
path?: string[];
|
|
299
|
+
[key: string]: unknown;
|
|
300
|
+
};
|
|
178
301
|
}
|
|
179
302
|
```
|
|
180
303
|
|
|
181
|
-
### Conditions
|
|
182
|
-
- `answered: false` → show only if survey not yet completed
|
|
183
|
-
- `cooldownDays: N` → do not show again until N days have passed since last display (per popup definition `id`)
|
|
184
|
-
|
|
185
304
|
## Events
|
|
186
305
|
|
|
187
|
-
|
|
306
|
+
The SDK emits:
|
|
307
|
+
|
|
188
308
|
- `popup_shown`
|
|
189
|
-
- `popup_clicked`
|
|
309
|
+
- `popup_clicked`
|
|
190
310
|
- `survey_completed`
|
|
191
311
|
|
|
192
312
|
Payload:
|
|
193
|
-
|
|
313
|
+
|
|
314
|
+
```ts
|
|
194
315
|
interface DeepdotsEvent {
|
|
195
316
|
type: 'popup_shown' | 'popup_clicked' | 'survey_completed';
|
|
196
317
|
surveyId: string;
|
|
@@ -199,106 +320,50 @@ interface DeepdotsEvent {
|
|
|
199
320
|
}
|
|
200
321
|
```
|
|
201
322
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
```typescript
|
|
205
|
-
{ type: 'time', value: 5000, surveyId: 'survey-1' } // after 5s
|
|
206
|
-
{ type: 'scroll', value: 50, surveyId: 'survey-2' } // at 50% scroll
|
|
207
|
-
{ type: 'exit', surveyId: 'survey-3' } // exit intent
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
## Automatic Trigger Derivation
|
|
211
|
-
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.
|
|
323
|
+
`data` often contains values such as:
|
|
212
324
|
|
|
213
|
-
|
|
214
|
-
|
|
325
|
+
- `popupId`
|
|
326
|
+
- `action`
|
|
327
|
+
- `userId`
|
|
215
328
|
|
|
216
|
-
|
|
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`.
|
|
217
330
|
|
|
218
|
-
|
|
331
|
+
## Important Behavior Notes
|
|
219
332
|
|
|
220
|
-
- `
|
|
221
|
-
- `
|
|
222
|
-
- `
|
|
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.
|
|
223
340
|
|
|
224
|
-
|
|
341
|
+
## Running The Examples Locally
|
|
225
342
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
show(surveyId, productId, data, emit, onClose) {
|
|
231
|
-
// 1. Display native modal
|
|
232
|
-
// 2. Render equivalent UI
|
|
233
|
-
// 3. Call emit('popup_clicked', surveyId, data) on first interaction
|
|
234
|
-
}
|
|
235
|
-
hide() { /* close modal */ }
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
const sdk = new DeepdotsPopups();
|
|
239
|
-
sdk.setRenderer(new MyNativeRenderer());
|
|
240
|
-
sdk.init({ mode: 'client', popups: [...] });
|
|
343
|
+
```bash
|
|
344
|
+
npm install
|
|
345
|
+
npm run build
|
|
346
|
+
python3 -m http.server 4173
|
|
241
347
|
```
|
|
242
348
|
|
|
243
|
-
|
|
244
|
-
1. Build the bundle: `npm run build`.
|
|
245
|
-
2. Load `dist/` in a WebView.
|
|
246
|
-
3. Bridge events: `window.ReactNativeWebView.postMessage(JSON.stringify(ev))`.
|
|
247
|
-
4. Initialize: `popups.init({...}); popups.autoLaunch();`.
|
|
349
|
+
Then open:
|
|
248
350
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
}
|
|
254
|
-
popups.on('popup_shown', forward);
|
|
255
|
-
popups.on('survey_completed', forward);
|
|
256
|
-
```
|
|
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`
|
|
257
355
|
|
|
258
|
-
|
|
259
|
-
Import types directly:
|
|
260
|
-
|
|
261
|
-
```typescript
|
|
262
|
-
import type {
|
|
263
|
-
DeepdotsConfig,
|
|
264
|
-
TriggerConfig,
|
|
265
|
-
ShowOptions,
|
|
266
|
-
DeepdotsEvent,
|
|
267
|
-
DeepdotsEventType,
|
|
268
|
-
EventListener,
|
|
269
|
-
} from '@magicfeedback/popup-sdk';
|
|
270
|
-
```
|
|
271
|
-
|
|
272
|
-
## Example Demo
|
|
273
|
-
See `examples/demo.html` for a runnable browser demo (uses client mode + fake definitions). To try it:
|
|
274
|
-
1. Build the project (`npm run build`).
|
|
275
|
-
2. Open `examples/demo.html` in a browser.
|
|
276
|
-
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://`.
|
|
277
357
|
|
|
278
358
|
## Development
|
|
279
359
|
|
|
280
360
|
```bash
|
|
281
|
-
npm
|
|
282
|
-
npm run build
|
|
283
|
-
npm run
|
|
284
|
-
npm
|
|
285
|
-
npm test # run vitest
|
|
286
|
-
npm run test:watch # watch tests
|
|
361
|
+
npm run build
|
|
362
|
+
npm run build:watch
|
|
363
|
+
npm run lint
|
|
364
|
+
npm test
|
|
287
365
|
```
|
|
288
366
|
|
|
289
|
-
Publishing uses `prepublishOnly` to ensure a fresh build.
|
|
290
|
-
|
|
291
|
-
## Notes & Limitations
|
|
292
|
-
- `server` mode currently simulates fetch; real network integration pending.
|
|
293
|
-
- `apiKey` is reserved for future authenticated endpoints.
|
|
294
|
-
- React Native renderer provided is a stub (example only).
|
|
295
|
-
- Sanitization of `message` HTML should be handled upstream if untrusted.
|
|
296
|
-
|
|
297
|
-
## Contributing
|
|
298
|
-
Issues & PRs welcome: https://github.com/MagicFeedback/deepdots-popup-sdk
|
|
299
|
-
|
|
300
367
|
## License
|
|
301
|
-
MIT
|
|
302
368
|
|
|
303
|
-
|
|
304
|
-
Open issues on the GitHub repository or contact maintainers.
|
|
369
|
+
MIT
|