Skip to main content
@ringg/react-native and ringg_flutter put the web widget’s voice calls, text chat, components and feedback screen into a native app, with the same conversation logic; for a website, use the web widget. Both packages are pre-1.0 (@ringg/react-native 0.4.0, ringg_flutter 0.1.5), so their APIs can change between minor versions: pin an exact version. Pick your framework with the switcher next to the table of contents; the configuration and events references have the same switch.

Before you start

An agent

A Webcall or voice agent; the app’s calls and chats go to it.

Its webcall key

The agentId and the Bearer key from the agent’s embed snippet.

Your app allowed

Each bundle or application ID, per platform and build flavor.
@ringg/react-native runs the widget in a React Native or Expo app with native views. You also need React 18+ and React Native 0.73+, in a development build or a bare app. Expo Go can’t load the native LiveKit modules, so use an Expo development build.Files you touch, depending on your setup:
app.json
App.tsx
ios
YourApp
Info.plist
android
app
src
main
AndroidManifest.xml

Install

Then install the three native modules. Autolinking only links native code in your app’s own node_modules, so the package can’t bundle them:
The config prop used below needs 0.4.0 or newer; on 0.3.0 you build the controller yourself.

Platform setup

Voice calls need a microphone, background audio and the native transport’s own manifest entries. Text chat needs none of it.

Expo

Add the plugin to app.json and rebuild the development build. It applies everything the widget needs, on both platforms.
app.json
To change the microphone prompt your users see:
app.json

Bare React Native

Bare apps have no config plugins, so add the same values by hand.
ios/YourApp/Info.plist
android/app/src/main/AndroidManifest.xml

Mount the widget

Pass a config and make the widget the last child of your root view, so its floating trigger and panel draw over the rest of the app. It opens its own connection and handles the microphone, and releases both when it unmounts.
App.tsx
Tapping the trigger opens the panel, and a chat or call connects to your agent.

Hand the install to Claude or Cursor. Fill in the agent ID, key and bundle IDs first.

Open in Cursor

Caller identity

The backend allow-lists an agent’s callers by the Origin header. Browsers attach one automatically, which is how domain whitelisting works for the web widget. Native HTTP sends nothing, so a webcall request without a caller identity is refused before authentication is even considered.Add the value to the agent’s allowed clients: open the agent, then Embed & Widgets → Install & domains → Allowed clients. Application ids differ per platform and per build flavor (.debug, .staging, .dev), so every build you ship needs its own entry. The value that was sent appears in the refused-call response, ready to paste.
Hybrid WebView runtimes report a shared identity (capacitor://localhost, ionic://localhost, file://) that is the same for every app built on that runtime. Allowing one admits all of them.
On React Native you pass the identity explicitly: appOrigin(BUNDLE_ID) in App.tsx above builds the <platform>://<bundleId> string, android://com.acme.app for that example. React Native can’t read the bundle ID without a native module, so pass it in: a constant, or a value from your app config, is enough. expo-application can read it from the OS, but it is native code, so adding it means rebuilding the app.

Notification sound

React Native has no built-in audio playback, so the widget plays no reply sound unless you pass a player through ports:
ports overrides anything the widget wires by default, and leaves the rest alone.

Testing hooks

Nodes carry a testID named after the web widget’s data-ringg attribute with a ringg- prefix: ringg-trigger-button, ringg-widget-root, ringg-header-title, ringg-message-input, ringg-end-call-confirm. header-status has no counterpart; its text is the surrounding node’s accessibilityLabel.

Verify the integration

  • The app is a development build, not Expo Go.
  • The trigger appears above your app content on both platforms.
  • Voice mode prompts for microphone permission and can start and end a call on a real device.
  • Every shipped flavor’s bundle ID is under Allowed clients.
  • Unmount the screen during a call and confirm the microphone indicator clears.

Known issues

  • No frosted-glass blur behind the header and composer; those surfaces are near-opaque.
  • The typing indicator has no gradient shimmer on the text; the ellipsis animates instead.
  • Agent replies render bold, italic, inline code, links, lists, headings, code blocks, blockquotes and rules. Markdown tables show as plain text.
  • Voice is unreliable on emulators: Android emulator networking often can’t set up the media connection, and iOS simulators have no microphone. Test voice on a real device.

Next steps

Configure the widget

Every option, its type and its default.

Handle events and actions

Lifecycle events, controller methods, agent actions.