Product analytics for Flutter
Pug ships a first-class Flutter SDK in Dart. Initialise it once and lifecycle tracking begins; add a route observer for screen views, and typed methods cover the well-known events with custom properties in extras.
Add Pug to Flutter
Four steps, start to first insight. Everything below uses the Flutter SDK exactly as it ships.
-
Add the package
One dependency covers iOS, Android, web, and desktop targets. It is the same event and identity model as the browser SDK, expressed in Dart.
flutter pub add pug_flutter -
Initialize in main()
Await Pug.init() before runApp(), with the bindings initialised first. The SDK reads persisted identity from platform storage at startup. It throws ArgumentError on an empty project id or key, and a second init while running is ignored with a logged warning.
lib/main.dartimport 'package:flutter/material.dart'; import 'package:pug_flutter/pug_flutter.dart'; Future<void> main() async { WidgetsFlutterBinding.ensureInitialized(); await Pug.init( 'YOUR_PROJECT_ID', const PugOptions(apiKey: 'pub_YOUR_PUBLIC_KEY'), ); runApp(const MyApp()); } -
Wire the route observer for screen views
App lifecycle is observed with no wiring at all. Navigation is not: add PugRouteObserver to your MaterialApp and each route change emits a screen_view on iOS and Android, with the route name from route.settings.name.
lib/app.dartMaterialApp( navigatorObservers: [PugRouteObserver()], home: const HomeScreen(), ); -
Identify people and track typed events
identify() ties the device’s activity to a person across sessions and platforms. The generated Pug.track namespace gives a method per well-known event with named parameters; anything custom goes through Pug.track(kind, props:) directly. Neither ever throws.
lib/checkout.dartawait Pug.identify('user_123', traits: {'plan': 'pro'}); // Typed method for a well-known event: Pug.track.purchase(productId: 'sku-1', amount: 99.50, currency: 'USD'); // Anything else, by name: Pug.track('tutorial_finished', props: {'step_count': 4});
What to watch for in Flutter
The specifics that decide whether the numbers you see are the numbers that happened.
Screen views need the route observer
Without PugRouteObserver in navigatorObservers you still get lifecycle and your own events, but no per-screen navigation event. Every event picks up the current and previous route as auto-properties once it is wired.
Lifecycle is automatic
app_open fires when the app enters the foreground and app_close on background, hidden, paused, or detached, sent immediately so it arrives before the OS kills the process.
Native Android has its own SDK
Flutter covers iOS, Android, web, and desktop from one codebase. A native Android app uses the Kotlin SDK instead; native iOS and React Native SDKs are in active development.
Consent, the mobile way
The same granted / cookieless / denied model as the browser, with its own Flutter surface: the docs cover how to gate capture behind an in-app prompt or an ATT dialog.
Product analytics in your Flutter app
-
Auto-tracking from init()
App lifecycle is observed with no wiring: app_open on foreground, app_close on background, sent immediately so it survives the OS killing the process.
-
Navigation events
A PugRouteObserver in your MaterialApp emits screen_view on iOS and Android, and every event picks up the current and previous route.
-
Typed well-known events
Pug.track.purchase(…), Pug.track.signup(…) and the rest are generated with named parameters; anything custom goes through Pug.track(kind, props:).
-
The same insights as web
Trends, funnels, retention, flows, and unified profiles: one project can hold your app and your website side by side.
Read it in the docs
The Flutter SDK reference goes deeper than a setup page can: every option, every event, and the edge cases.
Is the Flutter SDK production-ready?
The Flutter SDK is one of Pug’s six shipping SDKs (alongside Web, Android, Node, Go, and Ruby). It initialises in one call, auto-tracks lifecycle, and exposes typed methods for well-known events.
Why am I not seeing screen views?
Screen views come from the route observer, which is the one piece of wiring the SDK cannot do for you. Add PugRouteObserver() to navigatorObservers on your MaterialApp; lifecycle events and your own track() calls work without it.
What about native Android, iOS, or React Native?
Native Android ships today as a Kotlin SDK with its own setup page. Native iOS and React Native SDKs are in active development; until they ship, Flutter covers iOS, and any app can send events to the same backend over the HTTP API.
Can one project hold my app and my website?
Yes, and that is the point of unified profiles: identify() with the same user id from Flutter and from the Web SDK and both timelines resolve to one person, so a funnel can start on your marketing site and finish in the app.
Can I self-host the backend the app talks to?
Yes. Pug is AGPL-3.0 and self-hostable. Point the Flutter SDK at your own endpoint with PugOptions, or use Pug Cloud, free up to 100k events a month.
Add Pug to your Flutter app.
Create a project, add the snippet, and watch the Live view fill up. Or open the demo first: the real dashboard on a sample pet shop, with no sign-up.
Questions? Email hello@pug.sh