Web SDK (React)
Add live in-app micro-surveys to your React app. Like the iOS SDK, the browser SDK fetches your published survey config, evaluates triggers on-device, and presents the right survey at the right time — with no per-survey host code.
Beta. The Web SDK is in active dogfooding. APIs below are stable for MVP; expect small changes as the packages are hardened.
Packages
The Web SDK is two packages, published to npm under the @microsurveysai scope:
| Package | What it is |
|---|---|
@microsurveysai/react | React provider, hooks, and survey renderers. This is what most apps install. |
@microsurveysai/web-core | The framework-agnostic runtime (trigger evaluation, sampling, ingest). A dependency of react; use it directly only for non-React hosts. |
Source lives at MicroSurveysAI/microsurveys-web .
Requirements
- React 18+ (works with the Next.js App Router — the package ships
"use client"). - A project API key from the dashboard (
ms_live_…/ms_test_…) — the same browser-embeddable key the iOS SDK uses.
1. Install
npm
npm install @microsurveysai/react2. Wrap your app in the provider
import { MicroSurveysProvider } from "@microsurveysai/react";
export default function RootLayout({ children }) {
return (
<MicroSurveysProvider apiKey="ms_live_xxx">
{children}
</MicroSurveysProvider>
);
}The provider starts the client on mount: it fetches your survey config, flushes
any queued responses, and mounts the overlay host that presents auto-triggered
surveys. On the Next.js App Router you can render it straight from a Server
Component — the package is marked "use client".
3. Send events
Fire events with track(). When an event satisfies a survey’s trigger (and the
survey passes audience, sampling, and frequency rules), it presents itself after
the configured delay.
import { useMicroSurveys } from "@microsurveysai/react";
function CheckoutButton() {
const { track } = useMicroSurveys();
return <button onClick={() => track("checkout_completed", { plan: "pro" })}>Buy</button>;
}4. Identify the user (optional)
Attach a stable user id and properties so you can target audiences (e.g.
plan = "pro") and keep frequency caps consistent across sessions:
const { identify } = useMicroSurveys();
identify("user_123", { plan: "pro", locale: "en-US" });Without identify, the SDK uses a stable anonymous id persisted in
localStorage.
Inline surveys
To embed a specific survey in the page flow (e.g. a settings screen or a feedback
section) instead of an auto-triggered overlay, use <MicroSurvey>:
import { MicroSurvey } from "@microsurveysai/react";
<MicroSurvey surveyId="svy_abc" onComplete={(result) => console.log(result)} />;Inline embeds ignore trigger/platform targeting — rendering it is an explicit choice by you.
Configuration
<MicroSurveysProvider> accepts:
| Prop | Default | Description |
|---|---|---|
apiKey | — | Your project’s browser-embeddable key. |
apiBaseURL | MicroSurveys API | Override for self-hosted or to point at a specific environment. |
autoStart | true | Start on mount (fetch config, flush ingest). |
refreshOnForeground | true | Re-fetch config when the tab regains focus. |
How it works
- On-device eligibility. Config is fetched once (cached with an ETag) and all targeting — triggers, audience, deterministic sampling, frequency caps — is evaluated in the browser. No server round-trip decides what to show.
- Offline-safe ingest. Impressions and responses are queued in
localStorageand flushed with idempotency keys, so nothing is lost or double-counted. - Themeable. Survey appearance (colors, corner radius, position, font) is configured once in the dashboard and delivered with the config — no host CSS.
Troubleshooting
A survey isn’t showing. Confirm the survey is ACTIVE, the event name in
its trigger exactly matches what you pass to track(), and the user passes the
audience/sampling rules. Frequency caps also apply per user.
- CORS errors. The SDK endpoints send permissive CORS, so a browser
fetchfrom any origin works. If you see CORS errors, check thatapiBaseURLpoints at the right environment and the key is valid. - Nothing renders on first load. Config is fetched asynchronously on
start(); an eligible survey presents once config arrives and its trigger fires.