React Native
Hvorfor dette er anderledes end web
Sektion kaldt “Hvorfor dette er anderledes end web”MagicFeedback SDK’et er et browser-bibliotek: det afhænger af window, document og localStorage for at rendere undersøgelsens UI direkte i DOM’en. React Native har ingen DOM, så SDK’et kan ikke bruges direkte fra RN-kode.
Den understøttede vej er at rendere den hostede MagicFeedback-survey-URL inde i en WebView. Det giver dig:
- Den samme survey-UI dine web-brugere ser, uden at vedligeholde en parallel native-implementation.
- Alle spørgsmålstyper SDK’et understøtter.
- Livscyklus-events bygget tilbage til din RN-app via
postMessage.
Installation
Sektion kaldt “Installation”npm install react-native-webviewDu behøver ikke at installere @magicfeedback/native i RN-bundlen — WebView’et er host’en.
Host survey’en
Sektion kaldt “Host survey’en”Du skal bruge en offentlig URL, som starter SDK’et og renderer én formular. To muligheder:
- MagicFeedback-hostet survey-URL — bed din MagicFeedback-kontakt om den standalone survey-URL til dit
appId/publicKey. - Self-hostet tynd side — én HTML-fil i dit CDN, som indlæser SDK’et og renderer formularen. Send
appId,publicKeyog evt. metadata via query params.
Eksempel på self-hostet side (https://your-cdn.example.com/mf-survey.html):
<!doctype html><html> <head> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link rel="stylesheet" href="https://unpkg.com/@magicfeedback/native/dist/styles/magicfeedback-default.css" /> </head> <body> <div id="survey-root"></div> <script src="https://unpkg.com/@magicfeedback/native/dist/magicfeedback-sdk.browser.js"></script> <script> const params = new URLSearchParams(location.search); const appId = params.get("appId"); const publicKey = params.get("publicKey");
window.magicfeedback.init({ env: "prod" });
const form = window.magicfeedback.form(appId, publicKey); form.generate("survey-root", { addButton: true, addSuccessScreen: true, questionFormat: "slim", afterSubmitEvent: (event) => { window.ReactNativeWebView?.postMessage( JSON.stringify({ type: "afterSubmit", ...event }), ); }, onLoadedEvent: () => { window.ReactNativeWebView?.postMessage( JSON.stringify({ type: "loaded" }), ); }, }); </script> </body></html>Montér WebView’et i RN
Sektion kaldt “Montér WebView’et i RN”import { useState } from "react";import { Modal, View, StyleSheet } from "react-native";import { WebView, WebViewMessageEvent } from "react-native-webview";
const APP_ID = "APP_ID";const PUBLIC_KEY = "PUBLIC_KEY";const SURVEY_URL = `https://your-cdn.example.com/mf-survey.html?appId=${APP_ID}&publicKey=${PUBLIC_KEY}`;
export function FeedbackModal({ open, onClose,}: { open: boolean; onClose: () => void;}) { const handleMessage = (event: WebViewMessageEvent) => { try { const msg = JSON.parse(event.nativeEvent.data); if (msg.type === "afterSubmit" && msg.completed) { onClose(); } } catch { // ignorér beskeder der ikke er JSON } };
return ( <Modal visible={open} animationType="slide" onRequestClose={onClose}> <View style={styles.container}> <WebView source={{ uri: SURVEY_URL }} onMessage={handleMessage} /> </View> </Modal> );}
const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: "white" },});Render i en BottomSheet (eller en hvilken som helst anden RN-overflade)
Sektion kaldt “Render i en BottomSheet (eller en hvilken som helst anden RN-overflade)”Placér <WebView> inden i den RN-overflade du bruger. Mønsteret er identisk — modal, bottom sheet, dedikeret skærm — alle fungerer ens.
// Med @gorhom/bottom-sheetimport BottomSheet from "@gorhom/bottom-sheet";
export function FeedbackBottomSheet() { return ( <BottomSheet snapPoints={["80%"]}> <WebView source={{ uri: SURVEY_URL }} onMessage={handleMessage} /> </BottomSheet> );}// Dedikeret skærmexport function FeedbackScreen() { return <WebView source={{ uri: SURVEY_URL }} onMessage={handleMessage} />;}Bro for events fra WebView’et til RN
Sektion kaldt “Bro for events fra WebView’et til RN”Inde i survey-HTML’en kan hvert livscyklus-event fra SDK’et videresendes via postMessage:
form.generate("survey-root", { onLoadedEvent: () => window.ReactNativeWebView?.postMessage(JSON.stringify({ type: "loaded" })), beforeSubmitEvent: (e) => window.ReactNativeWebView?.postMessage(JSON.stringify({ type: "beforeSubmit", ...e })), afterSubmitEvent: (e) => window.ReactNativeWebView?.postMessage(JSON.stringify({ type: "afterSubmit", ...e })), onBackEvent: (e) => window.ReactNativeWebView?.postMessage(JSON.stringify({ type: "back", ...e })),});På RN-siden dispatch’er du på msg.type:
const handleMessage = (event: WebViewMessageEvent) => { const msg = JSON.parse(event.nativeEvent.data); switch (msg.type) { case "loaded": analytics.track("mf_loaded"); break; case "afterSubmit": if (msg.completed) onComplete(); break; case "back": break; }};Tilpas UI’et inde i WebView’et
Sektion kaldt “Tilpas UI’et inde i WebView’et”Da WebView’et indlæser din egen HTML, kontrollerer du CSS’et præcis som i en hvilken som helst web-app. Tilføj CSS-variabel-overrides til <head>:
<style> :root { --mf-primary: #0f766e; --mf-bg-primary: #ffffff; --mf-text-primary: #0f172a; } @media (prefers-color-scheme: dark) { :root { --mf-bg-primary: #0f172a; --mf-text-primary: #f8fafc; } }</style>Se Customization for hele variabel-overfladen.
Indsend fra RN uden WebView
Sektion kaldt “Indsend fra RN uden WebView”Har du ikke brug for det renderede UI og kun vil indsende feedback (fx en one-off NPS-prompt i native UI), kan du kalde MagicFeedbacks REST-API direkte fra RN — uden SDK. Det er samme payload som SDK’et sender internt; bed din MagicFeedback-kontakt om endpoint-kontrakten for din konto.