Skip to main content
The SDK ships four themes out of the box — light, dark, minimal, rounded — and a deep token system so you can override anything down to the corner radius of a button.
You can also style surveys without touching code using the Brand Kit in the dashboard. The SDK applies the Brand Kit on top of the base preset, then applies any init() overrides on top of that — so code always wins over the dashboard:base presetBrand Kit (dashboard)init() overrides
Theming controls colours, type, and shape. To change the modal’s text (buttons, placeholders, NPS anchors, progress counter), see Labels.

Pick a preset

Override tokens

Pass overrides to deep-merge on top of a preset. Only the keys you provide are changed.

Full token map

Custom fonts

typography.fontFamily (set in code or via the dashboard Brand Kit) only applies if the font is already loaded in your app — for example through expo-font or a native font link. The SDK does not bundle or load fonts. If the named font is not loaded, React Native silently falls back to the system font.

Dark mode & auto appearance

The dashboard Brand Kit has an Appearance setting — light, dark, or auto — delivered to the SDK as brandConfig.themeMode. No code is required: the SDK resolves the right scheme per survey.
  • auto follows the device appearance via React Native’s Appearance API. The provider subscribes to Appearance.addChangeListener, so if the user flips system dark mode while a survey is open, the modal re-themes live without closing.
    Appearance.getColorScheme() returns your app’s effective interface style, not the raw device toggle. If your app pins itself with Expo’s userInterfaceStyle (or a native overrideUserInterfaceStyle), auto follows that pinned style. Use userInterfaceStyle: "automatic" to follow the device, or drive the survey from your own in-app theme with the appearance prop below.
  • dark forces the SDK dark preset as the base; light keeps your configured init() preset.
  • The Brand Kit ships two colour palettes (light and dark). The matching one is mapped on top of the resolved base preset; any dark colour left unset in the dashboard inherits the built-in dark preset token.
Precedence is unchanged — init() overrides still win over the Brand Kit: resolved scheme presetBrand Kit paletteinit() overrides So a project with themeMode: "auto" and no custom dark colours renders a clean dark survey on dark devices automatically. Surveys with no Brand Kit (or a kit that predates dark mode) default to light — no behaviour change.

Follow your app’s theme

When your app manages light/dark itself (a theme context, a user preference, etc.) rather than only the OS toggle, auto’s device detection can disagree with what the user sees. Pass your app’s current appearance to <InsitoProvider appearance> and themeMode: "auto" surveys follow it instead of the device.
The prop only affects surveys whose Brand Kit themeMode is auto; light / dark Brand Kits always render their forced scheme. Updating the prop re-themes an open survey live, and switching back to "system" resumes device following.
If you instead pin your whole app’s native appearance with Expo’s userInterfaceStyle, set it to "automatic" so auto surveys follow the device. A fixed "dark" / "light" there makes Appearance.getColorScheme() always report that value.

Reading the resolved theme

If you want to extend Insito’s color system into the rest of your app (matching button colors, e.g.), read MicroSurvey.theme after init:
Or use the standalone helper for preview / Storybook scenarios:

Branding rules

  • components.showPoweredBy toggles the “Powered by Insito” badge. Resolution is: a per-survey showBranding value from the server (when present) wins, otherwise the theme token applies (the minimal preset defaults it to false). Plan-based branding enforcement happens server-side / in the dashboard, not as a client hard rule.
  • Keep colors WCAG AA-compliant — primary on background should hit 3:1 contrast minimum for usability. The default presets already pass.
  • modalMaxHeightFraction (default 0.85) sets the sheet’s max height as a fraction of the screen. Keep it roughly within 0.50.95 for a usable sheet; the value is applied as-is (not clamped by the SDK).

Custom rendering (advanced)

If the built-in bottom sheet isn’t enough — say you want an inline survey embedded inside a screen — you can render your own UI:
  1. Subscribe to useInsito() to read the activeSurvey reactively.
  2. When activeSurvey != null, render your custom UI from activeSurvey.questions.
  3. Call MicroSurvey.submitResponse(activeSurvey.surveyId, answers) when the user submits.
Note: <InsitoProvider> is still required for the legacy modal fallback. We’re tracking [INS-…] for a “headless mode” that drops the provider entirely.