beeper-inbox-native
v0.2.0
Published
React Native inbox components for Beeper.
Readme
beeper-inbox-native
React Native inbox components for Beeper.
The package uses the client-safe beeper-sdk/widget API and never accepts a
server API key. Your backend must mint a short-lived widget session token for
the signed-in subscriber.
<BeeperNativeInboxProvider
projectId={projectId}
publishableKey={publishableKey}
sessionToken={sessionToken}
refreshSessionToken={mintFreshSessionToken}
subscriber={{ subscriberId: user.id }}
push={{ token: fcmToken, platform: "android", autoRegister: true }}
>
<BeeperInboxPanel />
</BeeperNativeInboxProvider>Handling action presses
When a notification has an actionUrl, the built-in item shows an action button. By default,
pressing it opens the URL with Linking.openURL.
To route in-app instead (React Navigation, expo-router), pass onActionPress and return false
to skip the default:
<BeeperNativeInboxProvider
/* … */
onActionPress={({ actionUrl, item }) => {
if (actionUrl.startsWith("myapp://")) {
router.push(routeFromUrl(actionUrl));
return false; // handled: don't call Linking.openURL
}
// anything else (https links, say) falls through to Linking.openURL
}}
>- The handler can be
async; resolving tofalsealso skips the default. - The press is recorded for click analytics either way, in the background. A failed recording never blocks or cancels the action.
- If the handler throws, the URL is not opened and the error propagates, so a routing bug surfaces instead of silently falling back to the browser.
- If no app on the device can open the URL, the press does nothing rather than crashing.
Building your own UI with useBeeperInbox
useBeeperInbox() gives any component inside the provider the live inbox state and its
actions, and re-renders when the inbox changes:
import { useBeeperInbox } from "beeper-inbox-native";
function InboxTabIcon() {
const { unreadCount } = useBeeperInbox();
return <TabIcon name="bell" badge={unreadCount || undefined} />;
}
function CustomInbox() {
const { items, loading, refreshing, errorMessage, refresh, markRead, markAllRead, handleActionPress } =
useBeeperInbox();
return (
<FlatList
data={items}
keyExtractor={(item) => item._id}
refreshing={refreshing}
onRefresh={() => refresh({ silent: true })}
renderItem={({ item }) => (
<Row
item={item}
onPress={() => markRead(item._id)}
onAction={() => handleActionPress(item)}
/>
)}
/>
);
}| Field | |
| --- | --- |
| items, unreadCount | Inbox contents and unread total |
| loading, refreshing | First load, and background refresh |
| connectionState, errorMessage | "idle" \| "loading" \| "live" \| "error", and the last error |
| subscriber | The subscriber record, once loaded |
| refresh({ silent? }) | Re-fetch now; silent skips the loading state |
| markRead(id), markAllRead() | Mark items read (optimistic) |
| registerPushToken(token, options), unregisterPushToken(token) | Manual push device management |
| handleActionPress(item) | Run an item's action exactly as the built-in button does, including onActionPress |
Use handleActionPress in custom rows rather than calling Linking.openURL yourself, so click
analytics and your onActionPress routing stay consistent with the built-in UI.
useBeeperInbox throws if it is used outside BeeperNativeInboxProvider.
Push tokens
Use a native FCM token for both Android and iOS with the current Beeper push sender. Expo push tokens and raw APNs tokens require an additional provider integration.
