Appearance
Quick start
You need two things to render the chat: a server URL (where @aw-chat/server runs on your infrastructure) and a session token (a JWT your backend mints for the signed-in user — see Auth).
Packages below assume @aw-chat/* is available from your private npm (or a monorepo workspace:). How to publish: Publishing the SDK.
Web
bash
pnpm add @aw-chat/webtsx
import { AWChat } from "@aw-chat/web";
export function Support() {
return (
<div style={{ height: "100dvh" }}>
<AWChat
userId="user-123"
sessionToken={session.token}
serverUrl="https://chat.example.com"
telemetry={{
appVersion: "6.1.4",
hardwareId: "web",
osVersion: navigator.userAgent,
deviceLang: "ru",
}}
theme="light"
locale="ru"
onSessionExpired={() => {
/* refresh JWT and update sessionToken */
}}
/>
</div>
);
}<AWChat /> fills its container — give the parent a height. Add your web origin to the backend’s CORS_ORIGINS.
React Native
bash
pnpm add @aw-chat/react-native react-native-svg react-native-fast-imagetsx
import { AWChat } from "@aw-chat/react-native";
import * as DocumentPicker from "expo-document-picker";
export function SupportScreen() {
return (
<AWChat
userId="user-123"
sessionToken={session.token}
serverUrl="https://chat.example.com"
telemetry={{
appVersion: "6.1.4",
hardwareId: "iPhone15,2",
osVersion: "iOS 17.4",
deviceLang: "ru",
}}
fcmToken={fcmToken}
theme="light"
locale="ru"
// Required for attachments on native — without it the attach control is hidden.
// Use a document picker + opts.accept so chat matches web/TMA (photos + files).
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 ?? 0,
}));
}}
onSessionExpired={() => {
/* refresh JWT */
}}
/>
);
}Peers: react-native-svg (Expo includes it) and react-native-fast-image (renders images + plays the animated-WebP channel emoji; no expo-image, so OTA updates need no native rebuild). Details: React Native.
Telegram Mini App
Use @aw-chat/web and pass telegramChatId for Telegram push:
tsx
<AWChat
userId="user-123"
sessionToken={session.token}
serverUrl="https://chat.example.com"
telemetry={{ appVersion: "6.1.4", hardwareId: "tma", osVersion: "tma", deviceLang: "ru" }}
telegramChatId={String(tg.initDataUnsafe.user.id)}
/>Try it without a backend
Both SDKs ship a mock mode (demo prop) on built-in sample data (no network):
tsx
<AWChat demo userId="demo" sessionToken="" serverUrl="" telemetry={{ /* … */ }} />The repo examples/ apps also have a Mock/Live toggle for local/stand backends — see Try it — example apps for how to run each one (and the Expo dev build the React Native example needs on a device).
Next
- Props reference
- Auth & sessions
- Data model — where messages and comments are stored
- Limitations