Skip to the page
Docs
In-app chat

Docs Guides

In-app chat

People write to you from inside your app. You answer from Apparent, on the web or on your phone, and they see the answer right there. It's in every plan.

Expo and React Native apps today (apparent-expo 0.3.1 or newer).

Add the screen

The chat is one ready-made screen. It looks the same in every app; you pick the colour, the font and how round the corners are.

TypeScript
// app/help.tsx (expo-router), or any screen in your navigation
import { ApparentChatScreen } from "apparent-expo/chat-screen";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { router } from "expo-router";

export default function Help() {
  const insets = useSafeAreaInsets();
  return (
    <ApparentChatScreen
      theme={{ accent: "#0F7B5F", font: "Inter" }}
      onClose={() => router.back()}
      topInset={insets.top}
      bottomInset={insets.bottom}
    />
  );
}

Then open it from your settings or help button. Call Apparent.identify(userId) at sign-in, as you already do: each account gets its own chat.

Change the look

themeWhat it does
accentYour app's main colour: their messages and the send button. Text on it is dark or white, whichever reads better.
font, fontBoldYour app's font family.
radiusCorner roundness, 0 to 24 (default 18).
darkForce dark or light. By default it follows the phone.
backgroundOnly if your screens aren't plain white or near black.

Nothing else changes, on purpose: the chat works the same everywhere, at any text size and in right-to-left languages.

Your words, your language

Every word can be replaced with words. Anything you leave out stays English.

TypeScript
<ApparentChatScreen words={{ title: "Hilfe", placeholder: "Nachricht schreiben", emptyTitle: "Frag uns alles" }} />

Photos

Pass pickImage and a photo button shows. With expo-image-picker:

TypeScript
import * as ImagePicker from "expo-image-picker";

const pickImage = async () => {
  const r = await ImagePicker.launchImageLibraryAsync({ mediaTypes: ["images"], base64: true, quality: 0.6 });
  const a = r.canceled ? null : r.assets[0];
  return a?.base64 ? { base64: a.base64, uri: a.uri } : null;
};

<ApparentChatScreen pickImage={pickImage} />

A badge for new answers

TypeScript
import { useChatUnread } from "apparent-expo/chat-screen";

const unread = useChatUnread(); // answers they haven't seen yet; 0 when they never wrote

Answering

Every message comes to Chats in Apparent: on the web (the chat button at the top, or apparent.fyi/chats) and in the phone app, with a push. You see who wrote, their phone and app version, and what they did in the app right before writing. Answer there; they see it the next time the chat is open.

AI answers are coming next.

Your own chat screen

Prefer to draw it yourself? The same chat is there without a screen:

TypeScript
const off = Apparent.chat.subscribe((messages) => setMessages(messages)); // checks every few seconds while open
await Apparent.chat.send("Is there a dark mode?");                         // or send(text, { base64 })
Apparent.chat.markRead();                                                  // the answers were shown
const n = await Apparent.chat.unread();                                    // for a badge
await Apparent.chat.forget();                                              // the account was deleted

Privacy

Only the phone that wrote can read its chat: the SDK keeps a random chat key on the phone, and the app's key alone reads nothing. When someone deletes their account, call Apparent.chat.forget() and the chat is gone. Messages are kept with your other Apparent data and count toward your plan's chat messages a month.

Updated 2026-10-30 · Markdown · Report a mistake