ClientSphereDocs

Chat screen

The ready-made SupportChatScreen, its props, attachments, and building your own on the hooks.

SupportChatScreen is a complete chat built from React Native primitives: FlatList, TextInput, Pressable, Image. No UI library, no navigation dependency. Drop it into a screen of your own, or read it as a reference for how the hooks fit together.

<SupportChatScreen
  onPickAttachment={pickImage}
  onClose={() => navigation.goBack()}
/>

Props

PropDefaultMeaning
onPickAttachmentnoneAsync function returning a file or null. When absent there is no attach button
onClosenoneShows a Close control in the header that calls it
titlewidget nameHeader title
accentColorwidget primary colourHeader, send button, visitor bubbles
allowEscalatetrueShow "Talk to a human"
allowNewConversationtrueShow "Start a new conversation" once a conversation is closed

What it handles

  • Loading and error states for the provider, with a retry.
  • The email gate when the widget requires an email.
  • History with paging as you scroll up.
  • Sending, with the draft restored if the send fails.
  • Streaming AI replies as a live bubble, then the final message.
  • The agent typing indicator.
  • Attachments: uploading, chips for pending files, image previews in messages, and links for other files.
  • Closed conversations, with a prompt to start a new one.
  • Errors from sends and uploads, shown under the list.

Attachments

The SDK does not bundle a file picker. Give the screen one that returns { uri, name, type, size? }, which is the shape React Native's FormData streams from disk:

import * as ImagePicker from 'expo-image-picker';
 
async function pickImage() {
  const res = await ImagePicker.launchImageLibraryAsync({ quality: 0.8 });
  if (res.canceled) return null;
  const a = res.assets[0];
  return { uri: a.uri, name: a.fileName ?? 'photo.jpg', type: a.mimeType ?? 'image/jpeg', size: a.fileSize };
}

Images, PDFs and text files up to 5 MB are accepted. Anything else is refused before a request is made, with a message the screen shows. Uploads are limited to ten per minute.

If you use the hooks directly, upload(file) from useConversation returns an attachment object; pass an array of them as the second argument to send. To show an image from a message, use attachmentUrl(attachment) as the uri; the session token rides along as a query parameter so <Image> can fetch it.

Building your own

Everything the screen does comes from useConversation() and useSupportConfig(); see Hooks. A few things worth copying:

  • Invert the list. With FlatList inverted, the newest message sits at the bottom without scroll management, ListHeaderComponent is the right place for the streaming bubble and typing indicator, and onEndReached becomes "scrolled to the top", where loadOlder() belongs.
  • Merge, do not replace. messages is already deduplicated by id and in order. Render it as is.
  • Gate on status. When it is closed, hide the composer and offer startNew().
  • Throttle nothing yourself. notifyTyping() is already throttled; call it from onChangeText.

On this page