Integration

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.

Pug Flutter SDK: one SDK for Flutter pug_flutter Open source, AGPL-3.0

Setup

Add Pug to Flutter

Four steps, start to first insight. Everything below uses the Flutter SDK exactly as it ships.

  1. 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
  2. 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.dart
    import '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());
    }
  3. 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.dart
    MaterialApp(
      navigatorObservers: [PugRouteObserver()],
      home: const HomeScreen(),
    );
  4. 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.dart
    await 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});
Framework notes

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.

  • 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.

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