umami_analytics 0.2.0 copy "umami_analytics: ^0.2.0" to clipboard
umami_analytics: ^0.2.0 copied to clipboard

A production-quality Flutter package for Umami analytics with offline support, automatic page view tracking, and configurable logging.

umami_analytics #

A production-quality Flutter package for Umami analytics with offline support, automatic page view tracking, and configurable logging.

Features #

  • Page view & custom event tracking via Umami's /api/send endpoint
  • Offline queue with three modes: disabled, in-memory, or SQLite-persisted
  • Automatic page view tracking with UmamiNavigatorObserver
  • Session continuity via the x-umami-cache token
  • Enable/disable tracking — suppress HTTP sends in debug mode while keeping event logging
  • Configurable logging with two granularity flags and a pluggable callback
  • Minimal dependencies — only http and sqflite

Getting started #

Add to your pubspec.yaml:

dependencies:
  umami_analytics: ^0.1.0

Create a website in your Umami dashboard and note the Website ID.

Usage #

Basic setup #

import 'package:umami_analytics/umami_analytics.dart';

final umami = UmamiAnalytics(
  websiteId: 'your-website-id',
  endpoint: 'https://your-umami-instance.com/api/send',
  hostname: 'my-flutter-app',
  userId: 'optional-user-id', // enables stable session tracking across restarts
);

Track page views #

await umami.trackPageView(url: '/home', title: 'Home');

Track custom events #

await umami.trackEvent(
  name: 'button_clicked',
  url: '/home',
  data: {'button_id': 'subscribe'},
);

Automatic page view tracking #

Instead of manually calling trackPageView on every navigation, you can add UmamiNavigatorObserver to your app. It hooks into Flutter's navigation system and automatically tracks page views whenever a route is pushed or replaced. You can optionally filter which routes are tracked and customize how route names are mapped to URLs.

MaterialApp(
  navigatorObservers: [
    UmamiNavigatorObserver(
      analytics: umami,
      routeFilter: (route) => route.settings.name != null,
      routeNameMapper: (route) => route.settings.name!,
    ),
  ],
);

Queue configuration #

If a send fails (e.g. the device is offline), the event can be saved to a queue and retried later. The next successful send automatically triggers a flush of any queued events. There are three modes:

  • Disabled — events that fail to send are discarded.
  • In-memory — failed events are buffered in memory. Fast, but lost on app restart.
  • Persisted (default) — failed events are stored in a local SQLite database and survive app restarts. Events older than the configured TTL are automatically dropped during flush.
// No queue (fire and forget)
final umami = UmamiAnalytics(
  websiteId: 'id',
  endpoint: 'https://example.com/api/send',
  hostname: 'app',
  queueConfig: UmamiQueueDisabled(),
);

// In-memory queue (lost on restart)
final umami = UmamiAnalytics(
  websiteId: 'id',
  endpoint: 'https://example.com/api/send',
  hostname: 'app',
  queueConfig: UmamiQueueInMemory(maxSize: 200),
);

// SQLite-persisted queue (survives restarts, default)
final umami = UmamiAnalytics(
  websiteId: 'id',
  endpoint: 'https://example.com/api/send',
  hostname: 'app',
  queueConfig: UmamiQueuePersisted(
    maxSize: 500,
    eventTtl: Duration(hours: 48),
  ),
);

Disabling tracking #

Set enabled: false to suppress all HTTP requests while keeping event logging active. This is useful during development to see which events fire without polluting your production analytics.

final umami = UmamiAnalytics(
  websiteId: 'id',
  endpoint: 'https://example.com/api/send',
  hostname: 'app',
  enabled: !kDebugMode, // disable in debug mode
  enableEventLogging: true, // still see events in the console
);

Logging #

Logging is off by default. You can independently enable logging for tracking calls (enableEventLogging) and queue operations (enableQueueLogging). By default, logs go to debugPrint. If you want to route them somewhere else, provide a custom logger callback.

final umami = UmamiAnalytics(
  websiteId: 'id',
  endpoint: 'https://example.com/api/send',
  hostname: 'app',
  enableEventLogging: true,
  enableQueueLogging: true,
  logger: (level, message) => print('[$level] $message'),
);

Cleanup #

Call dispose() when you're done with the analytics instance — for example, in your app's dispose lifecycle method or before the app exits. This closes the SQLite database (if using a persisted queue) and the underlying HTTP client.

await umami.dispose();

API reference #

Method Description
trackPageView(url:, title:) Send a page view event
trackEvent(name:, url:, data:) Send a custom event with optional metadata
flush() Manually flush the offline queue
dispose() Close the queue database and HTTP client

Contributing #

Contributions are welcome! If you're a first-time contributor, please open an issue before submitting a pull request. See CONTRIBUTING.md for details.

License #

MIT

1
likes
160
points
201
downloads

Documentation

API reference

Publisher

verified publisherchris-kreymborg.com

Weekly Downloads

A production-quality Flutter package for Umami analytics with offline support, automatic page view tracking, and configurable logging.

Repository (GitHub)
View/report issues
Contributing

Topics

#analytics #umami #tracking #privacy #offline

License

MIT (license)

Dependencies

flutter, http, path, sqflite

More

Packages that depend on umami_analytics