Β§ 00Overview
The Flutter SDK speaks the same anonymous widget protocol your website chat uses β so customers can reach support from inside your mobile app, on the very conversations your agents already handle in the shared inbox.
It ships as two packages:
easylivechatβ headless protocol client plus reactive state, no UIeasylivechat_uiβ prebuilt, themeable widgets β launcher, chat screen, pre-chat form, attachments, CSAT
Β§ 01Install
Add the SDK to your app's pubspec.yaml. Most apps want easylivechat_ui β it re-exports the core. Reach for the headless easylivechat on its own only when you are building a fully custom UI.
dependencies: easylivechat_ui: ^0.1.0 # prebuilt UI + the headless core # β or, headless only β easylivechat: ^0.1.0
Requires Flutter 3.19 or newer. socket_io_client must be a 3.x release (Engine.IO v4) to match the server.
Β§ 02Quick start (drop-in UI)
Boot the client once with your workspace slug, then drop a launcher into your widget tree. The bubble opens a fully wired chat: pre-chat form, real-time thread, typing, attachments, CSAT, a working-hours offline form, plus server-driven theming and RTL.
import 'package:easylivechat_ui/easylivechat_ui.dart';
await EasyLiveChat.instance.boot(
const EasyLiveChatConfig(
apiBase: 'https://api.livechattools.com',
tenantSlug: 'acme', // your workspace slug
),
storage: SecurePrefsStorage(), // durable visitorId + JWT
);
// In your widget tree β a floating bubble that opens the full chat:
Stack(children: [ MyApp(), const EasyLiveChatLauncher() ]);Find your workspace slug in your dashboard. The launcher boots lazily on first open; pass a durable storage so the visitor identity survives app restarts.
Β§ 03Headless (build your own UI)
Prefer your own design system? Drive the headless client directly. Everything is exposed as ValueListenables and Streams you can bind to any state management.
import 'package:easylivechat/easylivechat.dart';
final chat = EasyLiveChat.instance;
await chat.boot(const EasyLiveChatConfig(
apiBase: 'https://api.livechattools.com', tenantSlug: 'acme'),
storage: myDurableStorage); // implement EasyLiveChatStorage
await chat.open(); // config β resume β prechat/anon β connect
chat.messages.addListener(rebuild); // ValueListenable<List<ChatMessage>>
chat.agentTyping.addListener(rebuild);
final res = chat.sendMessage('Hello!'); // optimistic; res.serverMessageId on ack
await chat.submitFeedback(rating: 5);open() orchestrates the full lifecycle: fetch config, resume any open conversation, gate on the pre-chat form or start anonymously, then connect the realtime socket.
Β§ 04How it works
When a session opens, the server mints a short-lived, per-conversation token. The SDK uses it for the REST calls and the realtime socket, re-mints it transparently before it expires, and reconnects with a gap-safe backfill when the mobile network drops.
Everything is anonymous-first: the SDK generates a durable visitor id on the device β no login required β and optionally collects a name and email through the tenant pre-chat form.
Security: never embed your tenant API key in a shipped app β that is a server-to-server secret. The Flutter SDK only ever uses the per-visitor session token, which is safe for a distributed client.
Β§ 05What needs server-side work
The full foreground chat experience works today with no backend changes. The one capability that needs server work is background push β delivering an βagent repliedβ notification to a closed app β because the backend currently pushes only to agents. A visitor push registry and fan-out is required to enable it; the SDK push hook stays inert until then.
Recommended follow-ups before a public launch: rate-limiting on session creation and message send, a token-refresh endpoint, and HEIC/MOV upload support for phone media.