Skip to content

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/web
tsx
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-image
tsx
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 ​

AW Chat SDK — integration & platform handoff docs.