React Native
SDK’et leveres med et dedikeret React Native entry point — @magicfeedback/popup-sdk/react-native — som klarer hele integrationen for dig: persistent storage, device info, platform, app-livscyklus, fejlopsamling og rendering af surveys i en Modal + WebView.
I de fleste apps er integrationen én komponent: pak din app ind i <DeepdotsProvider>.
Installation
Sektion kaldt “Installation”npm install @magicfeedback/popup-sdk react-native-webviewTo valgfrie pakker låser resten af funktionaliteten op. Installér begge, medmindre du har en grund til ikke at gøre det:
npm install react-native-mmkv react-native-device-infocd ios && pod install| Pakke | Påkrævet | Hvad den giver dig |
|---|---|---|
react-native-webview | ✅ | Renderer survey-UI’et |
react-native-mmkv | Anbefalet | Bevarer user_id på tværs af app-genstarter (tilbagevendende brugere) |
react-native-device-info | Anbefalet | Enhedstype, OS-version, model, app-version (Technology-metrikker) |
Alle er erklæret som valgfrie peer dependencies: SDK’et registrerer ved runtime, hvad der er installeret, og degraderer elegant. Uden MMKV lever user_id kun i hukommelsen, og der genereres et nyt ved hver opstart; uden react-native-device-info udelades enhedskonteksten.
Kom hurtigt i gang
Sektion kaldt “Kom hurtigt i gang”import { DeepdotsProvider } from '@magicfeedback/popup-sdk/react-native';
export default function App() { return ( <DeepdotsProvider config={{ apiKey: 'YOUR_PUBLIC_API_KEY', nodeEnv: __DEV__ ? 'development' : 'production', userId: 'customer-123', appVersion: '1.4.0', // Udelad `analytics` for at forblive i dry-run-tilstand (events logges, intet sendes). analytics: { publicKey: 'YOUR_ANALYTICS_PUBLIC_KEY', integration: 'YOUR_INTEGRATION_ID', }, }} > <YourNavigation /> </DeepdotsProvider> );}config tager samme objekt som init(config) — Provideren udfylder de React Native-specifikke felter (storage, device, platform) for dig.
Hvad Provideren tilslutter automatisk
Sektion kaldt “Hvad Provideren tilslutter automatisk”| Område | Hvordan |
|---|---|
| Persistent identitet | MMKV-instans (id: 'deepdots-sdk') når react-native-mmkv er installeret |
| Device info | react-native-device-info når den er installeret |
| Platform | Platform.OS → 'ios' / 'android' i analytics-konteksten |
| Engagement-tid | AppState → onForeground() / onBackground() (flusher ved baggrund) |
| Fejlopsamling | global.ErrorUtils → uhåndterede JS-fejl som deepdots_app_crash |
| Survey-rendering | ReactNativePopupRenderer + en Modal med en WebView, monteret efter behov |
To ting er ikke automatiske og kræver et par linjer fra dig: navigations-tracking og at starte triggerne.
Adgang til SDK’et
Sektion kaldt “Adgang til SDK’et”useDeepdots() returnerer den delte DeepdotsPopups-instans hvor som helst under Provideren. Hele analytics-API’et er tilgængeligt — se Analytics-guiden.
import { useDeepdots } from '@magicfeedback/popup-sdk/react-native';
function ProductScreen() { const dd = useDeepdots();
return ( <Button title="Læg i kurv" onPress={() => { dd.track('add_to_cart', { product_id: 'p-123', value: 49.9 }); dd.triggerEvent('added_to_cart'); }} /> );}Visning af popups
Sektion kaldt “Visning af popups”Provideren initialiserer SDK’et og henter popup-definitionerne, men den starter ikke triggerne — kald autoLaunch() én gang fra en komponent inde i Provideren:
function DeepdotsBootstrap() { const dd = useDeepdots();
useEffect(() => { dd.autoLaunch(); }, [dd]);
return null;}Alternativt kan du springe autoLaunch() over og vise popups imperativt med dd.triggerEvent('some_event') — matchende event-triggere udløses med det samme.
Sprogsegmenter
Sektion kaldt “Sprogsegmenter”En popup begrænset til bestemte sprog (segments.lang) evalueres mod det sprog, SDK’et bestemte ved init(): dit eksplicitte language, ellers navigator.language, ellers Intl-lokalet. Netop den sidste fallback er det, der får det til at virke under Hermes, hvor navigator.language ikke findes. Der matches på præfiks, så et segment på en matcher en-US.
Vil du styre målretningen eksplicit i stedet for at stole på registreringen — anbefalet, når din app har sin egen i18n — så send sproget med i konfigurationen:
<DeepdotsProvider config={{ apiKey: 'YOUR_PUBLIC_API_KEY', language: 'es-ES' }}>Når en popup vises, monterer Provideren en fuldskærms-Modal med en WebView med surveyen. Survey-HTML’en er selvstændig, men indlæser @magicfeedback/native fra et CDN, så rendering af en survey kræver netværksadgang. Popup-status (SHOWED / PARTIAL / COMPLETED) rapporteres automatisk til POST /sdk/popups, og det persistente user_id, session_id og den aktive mini_service injiceres i surveyens identitets-metadata.
Navigations-tracking
Sektion kaldt “Navigations-tracking”React Native har ingen History API, så skærmvisninger registreres ikke automatisk. Rapportér dem med setScreen(name) — SDK’et udsender et deepdots_page_view-event med varigheden af den forrige skærm, når du rapporterer den næste.
Med React Navigation:
import { NavigationContainer, createNavigationContainerRef } from '@react-navigation/native';import { useDeepdots } from '@magicfeedback/popup-sdk/react-native';
const navRef = createNavigationContainerRef();
function Navigation() { const dd = useDeepdots();
const report = () => { const route = navRef.getCurrentRoute(); if (route) dd.setScreen(route.name); };
return ( <NavigationContainer ref={navRef} onReady={report} onStateChange={report}> <YourStack /> </NavigationContainer> );}Skærmnavne normaliseres på samme måde som web-stier: query strings fjernes, og numeriske/UUID-segmenter kollapser til :id, så /product/123 og /product/456 begge rapporteres som /product/:id.
Avanceret: manuel opsætning uden Provideren
Sektion kaldt “Avanceret: manuel opsætning uden Provideren”Har du brug for din egen overflade (et bottom sheet, en dedikeret skærm) eller dit eget React-træ, så brug setupReactNative() og ReactNativePopupRenderer direkte. Begge kommer fra hoved-entry pointet.
import { useEffect, useRef, useState } from 'react';import { AppState, Modal, Platform, View } from 'react-native';import { WebView } from 'react-native-webview';import { MMKV } from 'react-native-mmkv';import DeviceInfo from 'react-native-device-info';import { DeepdotsPopups, ReactNativePopupRenderer, setupReactNative, type ReactNativeSurveyPayload,} from '@magicfeedback/popup-sdk';
const sdk = new DeepdotsPopups();
export function DeepdotsHost({ children }: { children: React.ReactNode }) { const [survey, setSurvey] = useState<ReactNativeSurveyPayload | null>(null); const rendererRef = useRef<ReactNativePopupRenderer | null>(null);
useEffect(() => { const renderer = new ReactNativePopupRenderer({ onShow: (payload) => setSurvey(payload), onHide: () => setSurvey(null), }); rendererRef.current = renderer;
// Sætter rendereren, injicerer storage/device/platform, kalder init() // og tilslutter AppState → onForeground/onBackground. Returnerer en oprydningsfunktion. return setupReactNative( sdk, { apiKey: 'YOUR_PUBLIC_API_KEY', nodeEnv: __DEV__ ? 'development' : 'production' }, { mmkv: new MMKV({ id: 'deepdots-sdk' }), deviceInfo: DeviceInfo, appState: AppState, platform: Platform.OS === 'ios' ? 'ios' : 'android', renderer, }, ); }, []);
return ( <> {children} {survey ? ( <Modal visible transparent animationType="slide"> <View style={{ flex: 1 }}> <WebView style={{ flex: 1 }} originWhitelist={['*']} javaScriptEnabled source={{ html: survey.html, baseUrl: 'https://sdk.deepdots.com/' }} onMessage={(e) => rendererRef.current?.handleMessage(e.nativeEvent.data)} /> </View> </Modal> ) : null} </> );}Rendereren er en bro, ikke en stub: onShow giver dig { surveyId, productId, html } klar til <WebView source={{ html }}>, og handleMessage oversætter WebView-beskeder til SDK-events — første interaktion → popup_clicked (PARTIAL), fuldførelse → survey_completed (COMPLETED).
Render surveyen uden SDK’ets kort (renderChrome)
Sektion kaldt “Render surveyen uden SDK’ets kort (renderChrome)”Fra 1.4.0: når du monterer din egen dekorerede container (en Modal, en bottom sheet eller en skærm med sit eget kort, baggrund, afrundede hjørner eller backdrop), send renderChrome: false i konfigurationen:
setupReactNative( sdk, { apiKey: 'YOUR_PUBLIC_API_KEY', renderChrome: false }, { /* deps */ },);Fra 1.3.0 tegner survey-HTML’en sit eget kort og backdrop (header med en lukkeknap, footer med navigationsknapperne, afrundet kort, nedtonet baggrund). Hvis din egen container også er dekoreret, stables de to til et “dobbelt modal” — et kort inde i et kort. renderChrome: false gør WebView-HTML’en gennemsigtig og kant-til-kant, så den fylder din container, mens surveyen forbliver fuldt funktionel (beskedbro, formular, back/start/complete/send-knapper og lukkeknappen). Du ejer den ydre ramme; SDK’et ejer surveyen.
Flaget påvirker kun React Native (survey-WebView-HTML’en). Det har ingen effekt på web-DOM-popuppen, og standard-<DeepdotsProvider> ignorerer det, fordi dens Modal allerede er gennemsigtig og fuldskærm (så den indbyggede sti viser ét enkelt kort). Brug det på den manuelle sti ovenfor.
Omstyling af selve surveyen
Sektion kaldt “Omstyling af selve surveyen”renderChrome afgør, hvem der tegner rammen. Vil du omstyle det, der er indeni — formuleringer, svarmuligheder, vurderingsskalaer samt SDK’ets egen header, fremdriftslinje og footer — så send dit eget stylesheet i surveyCss. Det indsættes som det sidste stylesheet i WebView’en, så det vinder i kaskaden uden at røre de standardværdier, alle Deepdots-kunder deler.
Den side viser også de klassenavne, du kan målrette. Fra 1.5.0 eksponerer SDK’et de samme kroge i både web-popuppen og denne WebView, så ét stylesheet dækker begge platforme.
setupReactNative(sdk, config, deps)
Sektion kaldt “setupReactNative(sdk, config, deps)”| Dep | Type | Standard når den udelades |
|---|---|---|
mmkv | MMKV-instans | config.storage, ellers in-memory |
deviceInfo | react-native-device-info-modul | config.device, ellers udeladt |
appState | AppState | Ingen livscyklus-tilslutning |
platform | 'ios' / 'android' / 'web' | config.platform, ellers 'web' |
renderer | PopupRenderer | SDK’ets standard-renderer |
errorUtils | global.ErrorUtils | globalThis.ErrorUtils hvis den findes |
Alle deps er valgfrie. Lavniveau-hjælpere eksporteres også, hvis du selv vil bygge delene: mmkvStorage(mmkv) (en synkron KeyValueStorage-adapter), collectRnDevice(deviceInfo) og buildSurveyHtml(options).