Embed in a mobile app
Put the Syncanix agent in a React Native or Flutter app by loading the web widget in a WebView — no native SDK required.
The Syncanix widget is a web component and a WebView is a browser, so the same one-tag embed that runs on your website runs unchanged inside a React Native or Flutter app. You get the full chat — mobile-responsive, with safe-area and soft-keyboard handling built in — without shipping a native SDK. This page is the recipe.
How it works
There is nothing mobile-specific to install. You host a small web page that carries the standard embed script, then load that page in a full-screen WebView. The widget boots inside the WebView exactly as it does in a desktop browser.
- Host a page that carries the embedA single HTML page on your own HTTPS origin — often a dedicated route such as /assistant — with the Syncanix script tag. Add that origin to your workspace's widget origin allow-list in the dashboard.
- Load that page in a full-screen WebViewPoint react-native-webview or webview_flutter at the page's URL and let it fill the screen. No other native wiring is needed for chat to work.
The page you host
Mount the chat so it fills the WebView, and name a token provider the widget calls each turn to act as the signed-in user. The viewport-fit=cover meta lets the chat respect the device's safe-area insets.
<!-- https://help.yourapp.com/assistant — a page you host, loaded by the WebView -->
<!doctype html>
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
<style>
html, body { margin: 0; height: 100%; }
#assistant { height: 100vh; }
</style>
<div id="assistant"></div>
<script
type="module"
src="https://cdn.syncanix.com/widget.js"
data-key="pk_live_..."
data-chat-size="embedded"
data-mount-target="#assistant"
data-token-provider="getSyncanixToken"
></script>
<script>
// The widget calls this once per turn; return the token your app injected.
window.getSyncanixToken = () => window.__SYNCANIX_TOKEN__ ?? undefined;
</script>The inline script defines the global the widget calls per turn; your native code sets window.__SYNCANIX_TOKEN__ before the page loads (below).
React Native
Render a full-screen WebView and inject the user's token before the page's content loads. Keep JavaScript enabled — it is on by default.
import { WebView } from 'react-native-webview';
export function AssistantScreen({ userToken }: { userToken: string }) {
return (
<WebView
source={{ uri: 'https://help.yourapp.com/assistant' }}
// Hand the signed-in user's token to the page before its content loads.
injectedJavaScriptBeforeContentLoaded={
`window.__SYNCANIX_TOKEN__ = ${JSON.stringify(userToken)}; true;`
}
// JavaScript is enabled by default; the widget needs it.
/>
);
}When the token refreshes, push the new value in with webviewRef.injectJavaScript('window.__SYNCANIX_TOKEN__ = "..."; true;').
Flutter
Use webview_flutter with JavaScript unrestricted, and set the token as the page starts loading.
final controller = WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted)
..setNavigationDelegate(NavigationDelegate(
onPageStarted: (_) => controller.runJavaScript(
'window.__SYNCANIX_TOKEN__ = ${jsonEncode(userToken)};',
),
))
..loadRequest(Uri.parse('https://help.yourapp.com/assistant'));
// In build(): return WebViewWidget(controller: controller);Signing in the user
A WebView shares no session with your native app, so the widget cannot see who is signed in unless you tell it. Hand it the user's token from your app's identity SDK; the widget then acts as that user, bounded by their own permissions — the same act-as-user model as on the web.
- The token is the user's JWT from your identity provider — the same one your API already trusts.
- It is read once per chat turn, so a refreshed token is picked up automatically.
- On sign-out, clear it (set window.__SYNCANIX_TOKEN__ to null) so the assistant stops acting as that user.
Before you ship
- Host the page on a real HTTPS origin (not a bundled file:// asset) and add that origin to the widget origin allow-list — the allow-list is matched by origin.
- Enable JavaScript in the WebView (React Native: on by default; Flutter: JavaScriptMode.unrestricted).
- Add viewport-fit=cover so the chat clears the notch and the home indicator.
- Let the soft keyboard resize the viewport rather than cover it; the widget keeps the composer in view via visualViewport.