API
These are the public methods of the DeepdotsPopups class. They cover everything a host application needs to mount the SDK, react to popups, and fire business events.
init(config)
Section titled “init(config)”Initializes the SDK and fetches the popup definitions from Deepdots.
popups.init({ apiKey: 'YOUR_PUBLIC_API_KEY', userId: 'customer-123', // optional});| Field | Required | Description |
|---|---|---|
apiKey | yes | Your Deepdots public API key. |
userId | no | Identifier sent with every popup event. |
language | no | BCP-47 language tag (e.g. es-ES). Drives both the analytics context and popup language targeting (segments.lang). Auto-detected from the browser (or Intl on React Native) when omitted. See Analytics → Language detection. |
contactAttributes | no | Internal user attributes to send to the Contact (requires userId). See setContactAttributes. |
debug | no | Enables the SDK’s debug output. Off by default. |
logger | no | Custom destination for that debug output. See Custom logger. |
renderChrome | no | React Native only (from 1.4.0). Default true. Set false when you mount your own decorated container so the survey WebView renders without the SDK’s own card and backdrop. See React Native → renderChrome. |
showProgressBar | no | From 1.5.0. Shows a Question X of Y label and a progress bar in the popup header. Omit it to respect whatever the platform configured for the survey. See Progress bar. |
surveyCss | no | From 1.5.0. Your own CSS, injected as the last stylesheet so it wins the cascade. The way to restyle the question area per integration. See Custom CSS. |
Progress bar
Section titled “Progress bar”The popup header can show how far along the survey is: a Question 2 of 3 label — the number in bold, the rest muted — above a thin progress bar.
popups.init({ apiKey: 'YOUR_PUBLIC_API_KEY', showProgressBar: true,});The flag has three states:
| Value | Behavior |
|---|---|
true | Always shown. |
false | Never shown. |
| omitted | Follows the showProgressBar setting configured for the survey in the platform. |
The bar only appears when there is more than one page, once past the start screen, and before the completion screen. It also honors the survey’s own progressUnit (fraction → Question 2 of 3, percentage → 66%), showProgressUnit, and loadingBarColor.
The label text is currently English only. If you need it localized, turn the unit off with showProgressUnit in the platform and render your own header.
Custom CSS
Section titled “Custom CSS”The question area — wording, options, rating scales — is rendered by the Surveys SDK with a stylesheet shared by every Deepdots customer. surveyCss lets you restyle it for your integration alone: the string is injected as the last stylesheet in the popup, so it wins the cascade without anyone having to change the shared defaults.
popups.init({ apiKey: 'YOUR_PUBLIC_API_KEY', surveyCss: ` /* Question wording: smaller and tighter than the default */ .magicfeedback-label { font-size: 15px; font-weight: 600; color: #1a1a1a; display: block; margin-bottom: 12px; line-height: 1.4; } .magicfeedback-sublabel { font-size: 13px; font-weight: 400; color: #6b7280; display: block; margin-bottom: 12px; } /* Options as plain rows instead of cards */ .magicfeedback-radio-container { box-shadow: none !important; border: none !important; background: transparent !important; border-radius: 0 !important; padding: 6px 0 !important; margin: 0 !important; } .magicfeedback-radio-container label { font-size: 14px; font-weight: 400; color: #1a1a1a; } `,});It applies to both the web DOM popup and the React Native survey WebView.
The class names come from @magicfeedback/native, and they are not always the obvious ones. The ones you are most likely to want:
| Element | Selector |
|---|---|
| Question wording | label.magicfeedback-label |
| Secondary line under the question | label.magicfeedback-sublabel |
| Radio / checkbox option row | .magicfeedback-radio-container, .magicfeedback-checkbox-container |
| Numeric rating scale | .magicfeedback-rating-number-container, .magicfeedback-rating-number-option |
| Free-text input | .magicfeedback-input |
Reaching the popup frame
Section titled “Reaching the popup frame”surveyCss is injected last, so it also reaches the SDK’s own chrome: header, progress bar, footer, completion screen. From 1.5.0 every hook below exists in both the web popup and the React Native survey, so one stylesheet covers both.
| Part | Selector |
|---|---|
| Popup container | #dd-popup · .deepdots-popup |
| Header row | .deepdots-popup-header |
| Header title | #dd-title · .deepdots-popup-title |
| Close icon | #dd-close |
| Progress block | #dd-progress · .deepdots-progress |
| Progress label | #dd-progress-label (#dd-progress-current, #dd-progress-total) |
| Progress bar | .deepdots-progress-track · #dd-progress-bar |
| Scrollable question area | #dd-main · .deepdots-popup-main |
| Footer | #dd-footer · .deepdots-popup-footer |
| All navigation buttons | .dd-nav-btn |
| Individual buttons | #dd-submit · #dd-back · #dd-start · #dd-complete |
| Completion screen | .deepdots-success |
| Validation banner | #dd-error · .deepdots-error-hint |
For colors, prefer the platform settings over CSS: the popup’s theme, position and font, and the survey’s own buttonPrimaryColor, buttonSecondaryColor and loadingBarColor. Those apply on both platforms and change without an app release. On React Native you can also hand the whole frame to your app with renderChrome: false.
Custom logger
Section titled “Custom logger”By default the SDK writes its debug output to console. Pass a logger to route it somewhere else — a log file, a remote logging service, Firebase, your own buffer — which is useful on React Native, where the Metro console is not available in production builds.
popups.init({ apiKey: 'YOUR_PUBLIC_API_KEY', debug: true, logger: { log: (...args) => myLogger.info(...args), warn: (...args) => myLogger.warn(...args), error: (...args) => myLogger.error(...args), },});Only log is required — warn, error, and info fall back to log when omitted. console itself satisfies the shape, so logger: console is valid and is the default.
interface DeepdotsLogger { log: (...args: unknown[]) => void; warn?: (...args: unknown[]) => void; error?: (...args: unknown[]) => void; info?: (...args: unknown[]) => void;}autoLaunch()
Section titled “autoLaunch()”Starts the triggers derived from the definitions loaded during init(). Call once after init().
popups.autoLaunch();triggerEvent(eventName)
Section titled “triggerEvent(eventName)”Fires a custom business event. Any popup in Deepdots configured with an event trigger that matches eventName will be shown (subject to cooldowns and targeting).
popups.triggerEvent('checkout_completed');See Triggers → event for details.
on(event, listener) / off(event, listener)
Section titled “on(event, listener) / off(event, listener)”Subscribe to the SDK events: popup_shown, popup_clicked, survey_completed.
const onShown = (event) => analytics.track('popup_shown', event);
popups.on('popup_shown', onShown);popups.off('popup_shown', onShown);See Events for the full payload shape.
setContactAttributes(attributes)
Section titled “setContactAttributes(attributes)”Sends internal user attributes that only your application knows — language, age, plan, segment, etc. — to the user’s Contact in Deepdots, so they can be used for popup targeting and segmentation.
Requires a userId in init(): the attributes are tied to that identity (the same id from your own system). Attribute values must be string, number, or boolean.
const sent = await popups.setContactAttributes({ language: 'es', age: 34, plan: 'premium',});The SDK only sends when the attributes changed since the last send — it keeps a diff in persistent storage — so you can call this on every user identification without generating extra requests. The returned promise resolves to:
true— the attributes were sent to the backend.false— nothing changed since the last send (or tracking is disabled, or there is nouserId).
Under the hood it performs POST /sdk/popups/contact with the body { publicKey, userId, userAttributes }. The Contact is created automatically on the first popup fetch, so no ordering is required.
You can also provide the initial attributes directly in init() via contactAttributes (equivalent to calling setContactAttributes right after init):
popups.init({ apiKey: 'YOUR_PUBLIC_API_KEY', userId: 'customer-123', contactAttributes: { language: 'es', plan: 'premium' },});