Appearance
Props reference
AWChatProps is the same shape on web and React Native unless noted.
Required (for live mode)
These four are required to talk to a backend. In demo mode they're optional.
| Prop | Type | Description |
|---|---|---|
userId | string | Your user id. Maps to Intercom external_id. |
sessionToken | string | JWT signed by your server (see Auth). |
serverUrl | string | AW Chat backend base URL on your infrastructure. Absolute https:// (or http:// on localhost). |
allowedServerUrls | string[] | Optional origin allowlist. When set, serverUrl must match one of these origins — blocks a bad prop / XSS from sending the Bearer elsewhere. Wallet hosts should pass their known API URL(s). |
telemetry | Telemetry | Device/app metadata (below). |
Telemetry:
| Field | Example |
|---|---|
appVersion | "6.1.4" |
hardwareId | "iPhone15,2", "web", "tma" |
osVersion | "iOS 17.4", "Android 14" |
deviceLang | "ru", "en" |
Optional
| Prop | Type | Default | Description |
|---|---|---|---|
user | { name?, email? } | — | Sets the Intercom contact's name/email (operator view). |
userDisplayName | string | — | Name on the user's own channel comments. See Comments. |
userAvatarUrl | string | — | Avatar on the user's own comments. Falls back to initials. |
theme | "light" | "dark" | "light" | Color scheme. |
locale | "ru" | "en" | "ru" | UI language. |
brandColor | string (hex) | glacial blue | Accent override. |
backgroundColor | { light?, dark? } | — | Optional screen background per theme. |
onClose | () => void | — | User backed out of hub/welcome — host should dismiss Support. |
onRouteChange | (route: { name }) => void | — | Internal screen changed (before paint on entry). Fires { name: "hub" } when <AWChat /> unmounts (not on ErrorPanel swap). Hide tab bar / header when name !== "hub". |
initialRoute | "hub" | "chat" | "ticket" | "hub" | Deep-link target. |
targetId | string | — | Ticket id for initialRoute: "ticket". |
skipWelcome | boolean | false | Skip the welcome gate; open the hub. Otherwise Welcome is shown on every open of Support; it survives brief same-tick remounts (e.g. network restore) and is cleared when the last <AWChat /> unmounts or on teardown(). |
demo | boolean | false | Mock data, no network. |
fcmToken | string | — | FCM device token → mobile push. |
telegramChatId | string | — | Telegram user id → TMA push. |
pollingInterval | number (ms) | 4000 | Base poll cadence. |
onSessionExpired | () => void | — | Fired on 401 — host should refresh the JWT. |
onError | (error) => void | — | Global error callback ({ code, message }). |
tsx
<AWChat
serverUrl="https://chat-api.example.com"
allowedServerUrls={["https://chat-api.example.com"]} // recommended in prod
onRouteChange={({ name }) => setChromeHidden(name !== "hub")}
/* … */
/>name is one of hub | chat | tickets | newTicket | channel | comments | soon (type AWChatRouteName from @aw-chat/core).
- Fired before paint with the initial route (deep links hide chrome with no flash).
- Fired on every internal navigation; consecutive duplicate
names are skipped. - Opening/closing the comments layer emits
comments/ back tochannel(channel stays mounted under the slide). - When
<AWChat />unmounts, fires{ name: "hub" }if the last screen was not hub (Strict Mode remounts and multi-instance are handled). Swapping to ErrorPanel does not restore chrome — Support stays fullscreen until the widget itself unmounts.
Account switch
When userId / sessionToken change (logout → another user), remount <AWChat /> or ensure the live store re-inits. Otherwise channel/comment state from the previous user can linger for the session.
Web-only
| Prop | Type | Default | Description |
|---|---|---|---|
fill | boolean | true | Fill the host container vs fixed size. |
React Native-only
| Prop | Type | Description |
|---|---|---|
onPickFiles | (opts: PickFilesOptions) => Promise<PickedFile[]> | Required for attachments. Host native picker. Honour opts.accept / multiple so chat matches web/TMA (photos + PDF/txt/mp4; comments stay images-only). Return { uri, name, type, size }[]. Without it, the attach control is hidden. |
tsx
import * as DocumentPicker from "expo-document-picker";
onPickFiles={async (opts) => {
const r = await DocumentPicker.getDocumentAsync({
multiple: opts.multiple,
copyToCacheDirectory: true,
type: [...opts.accept],
});
if (r.canceled) return [];
return r.assets.slice(0, opts.maxFiles).map((a) => ({
uri: a.uri,
name: a.name,
type: a.mimeType ?? "application/octet-stream",
size: a.size ?? undefined,
}));
}}Do not use a photos-only ImagePicker for chat — documents uploaded from web/TMA would then be invisible to native users (they can open them via the file chip; picking must allow the same MIME list).
Host stack (RN, system iOS swipe)
For native interactive pop, do not use a single <AWChat />. Mount AWSupportProvider + the exported screens (AWSupportHub, AWSupportChat, …) in your react-navigation Stack and pass navigation: AWSupportNavigation (navigate / goBack). See React Native → Host stack.
| Extra prop (provider) | Type | Description |
|---|---|---|
navigation | AWSupportNavigation | Required. Host maps SDK routes to Stack screen names. |
onOverlayChange | (overlay: "comments" | "complaint" | null) => void | Disable gestureEnabled while non-null. |
Deep linking
tsx
<AWChat initialRoute="ticket" targetId="t_12345" skipWelcome /* … */ />Push payloads include type (chat / ticket) and an id — map to initialRoute + targetId. In host-stack mode, call navigation.navigate({ name: "tickets", params: { openId } }) (or "chat") instead of remounting with initialRoute.