Chataptor is free, forever. Auto-translate customer conversations across 100+ languages and reach anyone, anywhere β no credit card, no trial. Create your account β
What you get
| π | Auto-translate customer β agent conversations across 100+ languages, in real time |
| π¨ | ChataptorChatScreen + ChataptorChatHeader widgets that match your Material theme out of the box |
| π | Translation Memory + Glossary keep brand terms and product names consistent |
| π§ | Email threading β chat closes, agent replies, full history stays unified |
| π | Pure-Dart core, MIT-licensed, no native wrappers, no black box |
In practice
π€ Customer in Tokyo
注ζγγεεγγΎγ ε±γγ¦γγΎγγ
β auto-translated, in real time
π§ Your agent reads
"My order hasn't arrived yet."
π§ Your agent replies in English
"Sure, let me check your order."
β auto-translated, in real time
π€ Customer reads in Japanese
γγ‘γγγγ注ζγη’ΊθͺγγΎγ
Same chat. No language switching, no copy-paste, no Google Translate.
Contents
This package ships the Chataptor singleton, ready-to-use chat widgets, theming, and localization. It re-exports the full chataptor core, so this is the only dependency you need.
Install
dependencies:
chataptor_flutter: ^0.2.0
flutter pub get
Quickstart
1. Initialise at app start
Call Chataptor.init once before runApp. Both siteId and widgetKey are found in the Chataptor admin console under Settings β API.
import 'package:chataptor_flutter/chataptor_flutter.dart';
import 'package:flutter/material.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Chataptor.init(
siteId: 'your-site-id',
widgetKey: 'pk_xxx',
);
runApp(const MyApp());
}
2. Add localization delegates
Wire ChataptorLocalizations into your MaterialApp:
MaterialApp(
localizationsDelegates: const [
ChataptorLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: ChataptorLocalizations.supportedLocales,
home: const HomeScreen(),
)
English and Polish are bundled out of the box. Ten additional locales arrive in v0.5.0.
3. Open the chat screen
ChataptorChatScreen is a full-page widget. Push it with the standard Navigator:
Navigator.of(context).push(
MaterialPageRoute(builder: (_) => const ChataptorChatScreen()),
);
The screen connects to Chataptor on mount and disconnects when popped β no lifecycle management required on your side.
Theming
ChataptorTheme controls all visual aspects of the chat UI. Two factory constructors cover the most common cases:
// Stand-alone defaults (purple accent, light backgrounds)
ChataptorTheme.light()
// Derives from the ambient Material theme β blends with your app automatically
ChataptorTheme.matching(context)
Override individual tokens via copyWith:
ChataptorTheme.light().copyWith(
primaryColor: Colors.teal,
bubbleRadius: const BorderRadius.all(Radius.circular(8)),
)
Pass the theme to ChataptorChatScreen:
ChataptorChatScreen(
theme: ChataptorTheme.matching(context).copyWith(
primaryColor: Theme.of(context).colorScheme.secondary,
),
)
Custom UI
For full control over the UI, use the core ChataptorClient directly. Access the process-wide instance via Chataptor.instance, or inject a specific client with ChataptorScope:
// Access the singleton
final client = Chataptor.instance;
// Or inject a specific client into a subtree
ChataptorScope(
client: myClient,
child: const MyChatWidget(),
)
Subscribe to streams directly:
final client = Chataptor.instance;
// Incoming messages
client.messages.listen((message) {
setState(() => _messages.add(message));
});
// Connection state
client.connectionState.listen((state) {
if (state is Connected) _setReady();
});
// Per-language site config (welcome message, team name, offline mode)
client.siteConfigStream.listen((config) {
setState(() => _teamName = config.activeHeaderTitle('pl'));
});
// Live roster of currently-online agents (id, name, avatar URL, initials)
client.onlineAgentsStream.listen((agents) {
setState(() => _onlineAgents = agents);
});
// Send
final result = await client.sendMessage('Hello!');
The drop-in ChataptorChatScreen already consumes these streams to
render ChataptorChatHeader (avatar stack of online agents, team name
from SiteConfig.activeHeaderTitle, live Online/Offline indicator) β
matching the production web widget on chataptor.com sites. Headless
integrations get the same data so a custom header can show the same
presence info.
Testing β wire a fake client into your widget tests
Inject a FakeChataptorClient via ChataptorScope to test your UI without a network connection:
import 'package:chataptor/chataptor.dart';
import 'package:chataptor/testing.dart';
import 'package:chataptor_flutter/chataptor_flutter.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('chat screen mounts with connected client', (tester) async {
TestWidgetsFlutterBinding.ensureInitialized();
final fake = FakeChataptorClient(
initialConnectionState: const Connected(),
);
await tester.pumpWidget(
ChataptorScope(
client: fake,
child: const MaterialApp(home: ChataptorChatScreen()),
),
);
expect(find.byType(ChataptorChatScreen), findsOneWidget);
// Simulate a connection drop
fake.inject.connectionState(
const Disconnected(DisconnectReason.networkError),
);
await tester.pump(const Duration(milliseconds: 100));
});
}
Use fake.inject to drive the client into any state, and fake.recorded to assert on what the UI sent.
Requirements
| Minimum | |
|---|---|
| Flutter | 3.35.0 |
| Dart | 3.9.0 |
| iOS | 12.0 |
| Android | API 21 |
Documentation
| Getting started | Five-minute walk-through from zero to working chat |
| Identified customers | HMAC verification recipe with server-side snippets |
| Multi-instance setup | Running multiple Chataptor sites in one app |
| Architecture | Locked design decisions |
| Changelog | Per-version release notes |
| Example app | Runnable demo |
License
MIT Β© 2026 Chataptor
Libraries
- chataptor_flutter
- Chataptor Flutter β drop-in widgets, singleton, and lifecycle management
on top of the
chataptorcore.