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. There is no Flutter wrapper in between.
-
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 and React Native are in development
Flutter is the shipping mobile SDK today. Native Android, iOS, and React Native SDKs are in active development and landing by launch; until then a native app can send events to the same backend over the HTTP API.
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.
Pug + Flutter: common questions
Is the Flutter SDK production-ready?
The Flutter SDK is one of Pug’s three shipping SDKs (alongside Web and Node). 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, iOS, and React Native SDKs are in active development and landing by launch. Today, mobile is covered by the Flutter SDK; for native apps you can send events to the same backend over the HTTP API in the meantime.
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 the free cloud during open beta.
Add Pug to your Flutter app.
Open-source product analytics with unified profiles. Self-host under AGPL-3.0, or use the free cloud during open beta.
Questions? Email hello@pug.sh