Skip to main content

herald_widgets 1.2.0 copy "herald_widgets: ^1.2.0" to clipboard
herald_widgets: ^1.2.0 copied to clipboard

Track Herald events from Flutter widgets: screen views when a screen becomes visible, impressions when something is really on screen, and taps.

Herald widgets #

An optional package for tracking Herald events from Flutter widgets: screen views each time a screen becomes visible, impressions when something is really on screen, and taps in widgets that have no bloc.

You don't need it to use Herald. A screen, bloc or view model can track its own events, screen views included, through EventTrackerService. Use this package when tracking from the widget tree is the simpler fit, such as counting a screen each time the user comes back to it.

dependencies:
  herald_widgets: ^1.2.0

Set it up once #

final routes = HeraldRouteObserver();

runApp(
  HeraldScope(
    analytics: herald, // or your DI's EventTrackerService
    routes: routes,
    child: MaterialApp(
      navigatorObservers: [routes], // go_router: GoRouter(observers: [routes])
      home: const HomePage(),
    ),
  ),
);

Screen views, owned by each screen #

@override
Widget build(BuildContext context) => TrackScreenView(
  event: ProductScreenViewed(productId),
  child: Scaffold(...),
);

It tracks each time the screen becomes visible: when it appears, when the user comes back to it, and when the app comes back to view with it on top. Rebuilds don't count, and neither do dialogs, bottom sheets or menus over it.

To track when the user leaves a screen:

TrackOnScreen(
  event: CheckoutLeft(itemsInCart: cart.length),
  on: ScreenMoment.hidden,
  child: CheckoutView(cart),
)

Taps #

ElevatedButton(
  onPressed: () => HeraldScope.of(context).track(PromoBannerTapped(promo.id)),
  child: const Text('See the offer'),
)

Events that come from your app's logic belong in its bloc or view model. This is for small widgets that have none.

Impressions #

TrackImpression(
  event: OfferShown(offer.id),
  threshold: 0.5, // half of it on screen
  minVisibleDuration: const Duration(seconds: 1), // for a second, not a fast scroll
  child: OfferCard(offer),
)

It counts once per appearance: something that leaves the screen and comes back counts again. Give events value equality, so a rebuild with an equal event doesn't start the count again.

Tests and previews #

Wrap the widget in a HeraldScope with a FakeAnalyticsProvider from herald_testing, and add a HeraldRouteObserver for screens:

final analytics = FakeAnalyticsProvider();
final routes = HeraldRouteObserver();
await tester.pumpWidget(
  HeraldScope(
    analytics: analytics,
    routes: routes,
    child: MaterialApp(navigatorObservers: [routes], home: const ProductPage('p1')),
  ),
);

analytics.assertTracked('product', (event) => event.param('product_id', 'p1'));

A widget preview can do the same through @Preview(wrapper: ...).

Limits #

  • Tabs aren't screens. Switching tabs doesn't push a page, so track it from the code that switches.
  • A nested Navigator, such as go_router's shell route, needs a HeraldRouteObserver of its own, given to a HeraldScope around it.

Documentation #

It works with herald, the core, whose page lists every Herald package. The Herald website has the guides, and the repository has an example app.

0
likes
160
points
527
downloads

Documentation

Documentation
API reference

Publisher

unverified uploader

Weekly Downloads

Track Herald events from Flutter widgets: screen views when a screen becomes visible, impressions when something is really on screen, and taps.

Repository (GitHub)
View/report issues
Contributing

Topics

#analytics #tracking #widget

License

Apache-2.0 (license)

Dependencies

flutter, herald, visibility_detector

More

Packages that depend on herald_widgets