Flutter SDK for Rybbit, the open-source web analytics. It tracks screen views, custom events, errors and user identity from Flutter apps on Android, iOS, macOS, Windows, Linux and Web.
- 📱 Screen view tracking - Through
NavigatorObserveror by callingscreenView() - 🎯 Custom events - With typed properties
- 🐛 Automatic error tracking - Captures Flutter framework errors, async exceptions, and zone errors
- 🧾 Manual error tracking -
trackError()with stack traces and context - 👤 User identification -
identify()with traits, backfills 30 days - 🔑 Stable device id - One
anonymous_idper install, so a changing IP or an app update doesn't split one device into several users - 🛒 GA4-style typed events - 23 methods (e-commerce, auth, engagement, CMS, lead gen)
- 💾 Persistent offline queue - Stored in Hive, kept across app restarts
- 🔄 App lifecycle tracking - Sends
app_open,app_foreground,app_background - 📶 Connectivity monitoring - Sends the offline queue when the device is back online
- 🖼️ App icon upload - Uploads the app icon to the Rybbit dashboard (
autoUploadIcon, off by default) - 🌍 Platforms - Android, iOS, macOS, Windows, Linux, Web
- Flutter >= 3.10.0
- Dart >= 3.0.0
- Any Rybbit server, self-hosted or cloud
/api/track on a stock Rybbit rejects fields it does not know, so the SDK
detects that on its first event and stops sending app_version and
device_model; everything else is reported as usual. A server with
PR #921 merged keeps both, and
the app version and device model then show up in sessions and filters. The
switch is automatic - there is nothing to configure either way.
Dependencies: http | device_info_plus | package_info_plus | connectivity_plus | hive | path_provider
dependencies:
rybbit_flutter_sdk: ^0.3.0dependencies:
rybbit_flutter_sdk:
git:
url: https://github.com/nks-hub/rybbit-flutter-sdk.git
ref: mainimport 'package:flutter/material.dart';
import 'package:rybbit_flutter_sdk/rybbit_flutter_sdk.dart';
void main() {
Rybbit.runApp(() async {
WidgetsFlutterBinding.ensureInitialized();
await Rybbit.init(
host: 'https://your-rybbit-instance.com',
siteId: 'your-site-id',
);
runApp(MaterialApp(
navigatorObservers: [RybbitNavigatorObserver()],
home: const HomeScreen(),
));
});
}// Screen view
Rybbit.instance.screenView('/checkout', title: 'Checkout');
// Custom event
Rybbit.instance.event('button_click', properties: {'button': 'cta'});
// Error tracking
Rybbit.instance.trackError(error, stackTrace);
// User identification
Rybbit.instance.identify('user-123', traits: {'plan': 'pro'});Every event carries an anonymous_id. The server hashes it into user_id
instead of falling back to a hash of IP + user agent, which on mobile changes
with every network switch and app update and turns one phone into several
"users".
The SDK generates and stores a UUID on first run. When the app already has its own id, such as a device hash it sends to its backend or an install UUID, pass it in and analytics uses the same identifier as your records:
await Rybbit.init(
host: 'https://analytics.example.com',
siteId: 'my-site',
anonymousId: myDeviceHash,
);
// or later, if the id isn't known at init
Rybbit.instance.setAnonymousId(myDeviceHash);The id survives restarts, but not a reinstall.
- API reference - Classes, methods and configuration options
- Examples - Setup, navigation, e-commerce, error handling, testing
- Changelog
- Rybbit - Open-source web analytics platform
- @nks-hub/rybbit-ts - TypeScript SDK for web
- rybbit-app - Flutter dashboard for Rybbit
- @nks-hub/rybbit-mcp - MCP server for querying Rybbit from AI assistants
flutter pub get
flutter analyze
flutter testContributions are welcome! For major changes, please open an issue first.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'feat: description') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- 📧 Email: dev@nks-hub.cz
- 🐛 Bug reports: GitHub Issues
GNU General Public License v3.0 — see LICENSE for details.
Made with ❤️ by NKS Hub