Brace chat for Flutter

Add your Brace live chat to a Flutter app. The chat opens full screen with your channel's colours, docs and forms, exactly as it looks on your website.

Install

flutter pub add brace_chat

Needs Flutter 3.47 or newer (Dart 3.13), because the web view plugins it uses do.

Android needs minSdkVersion 24 or higher and the INTERNET permission (Flutter adds it in debug builds only; add it to android/app/src/main/AndroidManifest.xml for release).

On iOS, add NSCameraUsageDescription to ios/Runner/Info.plist (for example "Lets you send a photo in the support chat"). The chat's attach button offers Take Photo, and iOS closes an app that opens the camera without that line.

Set up

Configure once at startup. The website token is under Settings > Channels > Live Chat > Installation in Brace.

final navigatorKey = GlobalKey<NavigatorState>();

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  BraceChat.instance.configure(
    BraceChatConfig(websiteToken: 'YOUR_WEBSITE_TOKEN'),
    navigatorKey: navigatorKey, // optional: lets open() work without a BuildContext
  );
  runApp(MaterialApp(navigatorKey: navigatorKey, home: const HomePage()));
}

The chat loads in the background, so it opens instantly, and it keeps its conversation while it is closed.

Open the chat

BraceChat.instance.open(context); // or open() with a navigatorKey
BraceChat.instance.close();
BraceChat.instance.toggle(context);

To render your own chat button:

ValueListenableBuilder<BraceChatState>(
  valueListenable: BraceChat.instance.state,
  builder: (context, state, _) => state.isAvailable
      ? FilledButton(onPressed: () => BraceChat.instance.open(context), child: const Text('Chat with us'))
      : const SizedBox.shrink(), // the workspace is paused
);

The widget's own close button and the back button both close the chat.

Identify your signed-in user

BraceChat.instance.setUser(BraceChatUser(
  identifier: 'user-42', // your own stable id for this person
  name: 'Ada Lovelace',
  email: 'ada@example.com',
  phoneNumber: '+15551234567',
  identifierHash: hashFromYourServer,
));

Nothing is sent to Brace until the person actually chats. When they sign out, call BraceChat.instance.reset(), which forgets them and their conversations on this device.

Identity verification

If identity verification is on for your Live Chat channel, Brace only accepts a user whose identifierHash is HMAC-SHA256(secret key, identifier). The secret key is in the channel's Security tab. Compute the hash on your server and send it to the app with the user's profile. Never put the secret key in the app. The hash signs the identifier, not the email.

Events

BraceChat.instance.events.listen((event) {
  switch (event) {
    case BraceChatUnavailable(): hideChatButton();
    case BraceChatBrandColor(:final color): tint(color);
    default: break;
  }
});
Event When
BraceChatOpened, BraceChatClosed the chat was shown or hidden, whoever asked
BraceChatReady the chat page has loaded
BraceChatBrandColor the channel's brand colour arrived, as a CSS colour string
BraceChatUnavailable the workspace is paused or suspended and takes no messages; opening does nothing until the next launch

Options

BraceChatConfig Default
websiteToken required the Live Chat channel's website token
widgetUrl https://widget.brace.chat/ where the widget is served
baseUrl https://app.brace.chat the Brace server
braceUrl baseUrl the Brace dashboard address

Links in the chat (attachments, links in messages) open in the system browser. On Android the attach button opens the system file picker.

Libraries

brace_chat
Brace live chat for Flutter apps.