Customization
Wherd is designed to go from "looks native to my app" to "fully custom UI" in three tiers. They compose — pick the highest one you need.
Precedence (lowest → highest): SDK defaults → dashboard config → theme prop.
Tier 1 — Theme tokens
Pass a theme to the provider. Works identically on web and React Native.
<WherdProvider
theme={{
colorScheme: "system", // "light" | "dark" | "system" (default: light)
colors: { primary: "#16a34a" },
radius: 16,
typography: { fontFamily: "Inter, sans-serif" }, // web only
}}
/>
Available color tokens: primary, primaryForeground, background,
foreground, muted, mutedForeground, border.
Tier 2 — Server-driven config (no release)
In the dashboard (Settings → Widget config) you control theme, which modules are enabled (Messages / Ideas / What's New), copy, activation (FAB / shake), and auto-show (announcements / release notes). The SDK fetches this at startup, so you can restyle or toggle features without shipping an app update — uniquely useful for mobile.
A theme prop in code still overrides server config where both set a value.
Positioning the launcher
The floating launcher (FAB) defaults to the bottom-right corner. Move it to clear
a tab bar or switch corners via the fab prop on <MessagesWidget>:
<MessagesWidget
fab={{
placement: "bottom-right", // or "bottom-left"
offset: { bottom: 96, side: 20 }, // bump `bottom` above a tab bar
label: "Messages", // optional pill label
}}
/>
For full control over placement, hide the built-in launcher and trigger from your own UI (e.g. a tab-bar button) — see Tier 3.
Activation: shake instead of a FAB (React Native)
Override how the widget is opened with the activation prop on <WherdProvider>:
<WherdProvider activation={{ fab: false, shake: true }}>
fab— show/hide the floating launcher.shake— open the widget when the device is shaken. Requiresexpo-sensors(npx expo install expo-sensors); without it, shake is a no-op.
With shake enabled, the SDK shows a one-time hint on first launch so users
discover the gesture (important when there's no FAB). The activation prop
overrides the dashboard's server config.
Auto-show
When there's a new announcement (or a new release note), the SDK can open the widget automatically on launch so users don't miss it — once per item.
- Announcements — on by default (time-sensitive: outages, contests, maintenance).
- Release notes — off by default (less urgent).
Configure per project in the dashboard, or override in code:
<WherdProvider autoShow={{ announcements: true, changelog: false }} />
Announcements render as severity-styled banners (info / warning / critical) at the top of the widget; users can dismiss them.
Tier 3 — Headless
The prebuilt components are built entirely on exported hooks, so you get full parity building your own UI:
import { useComposer, useMessages, useFeatureRequests, useChangelog, useWherd } from "@wherdkit/react";
function MyComposer() {
const { body, setBody, submit, submitting, submitted } = useComposer();
if (submitted) return <p>Thanks!</p>;
return (
<form onSubmit={(e) => { e.preventDefault(); submit(); }}>
<textarea value={body} onChange={(e) => setBody(e.target.value)} />
<button disabled={submitting}>Send</button>
</form>
);
}
Use useMessages() to build your own inbox/conversation UI (threads, replies,
unread). You can mix tiers: use the prebuilt <WhatsNew /> but a custom composer,
etc. Skip <MessagesWidget /> entirely and trigger views with
useWherd().open("messages" | "featureRequests" | "changelog").
See API reference for every hook's return shape.