4

I have been analyzing different navigator observers by 3rd party integrations (e.g., SentryNavigatorObserver, FirebaseAnalyticsObserver) to make identical for tools that don't have it by default. But I noticed that neither of these is really catching all route transitions. I see it when they display data in their corresponding consoles. Yes, it works with push/pop, but any transitions within the same level with go are not being tracked. Which is very annoying. Anybody knows the way to solve it?


For example,

The transition from /page to /page/detail is observed.

The transition from /pageA to /pageB is not.

krishnaacharyaa
  • 14,953
  • 4
  • 49
  • 88
Roman Shirokov
  • 329
  • 4
  • 12

2 Answers2

9

Extend Observer from NavigatorObserver


Code

 GoRouter(
  initialLocation: '/',
  navigatorKey: _rootNavigatorKey,
  observers: [
    GoRouterObserver(),  Specify your observer here
  ],
  routes: [
    GoRoute(
      ...
    )
    GoRoute(
      ...
    ),
  ],
);

class GoRouterObserver extends NavigatorObserver {
  @override
  void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) {
    print('MyTest didPush: $route');
  }

  @override
  void didPop(Route<dynamic> route, Route<dynamic>? previousRoute) {
    print('MyTest didPop: $route');
  }

  @override
  void didRemove(Route<dynamic> route, Route<dynamic>? previousRoute) {
    print('MyTest didRemove: $route');
  }

  @override
  void didReplace({Route<dynamic>? newRoute, Route<dynamic>? oldRoute}) {
    print('MyTest didReplace: $newRoute');
  }
}
krishnaacharyaa
  • 14,953
  • 4
  • 49
  • 88
  • 2
    "+1" Thanks, this information is difficult to find in the docs. With this solution you can see when routes are pushed/popped/removed. I can now use this to track page/route views with google analytics, grabbing the name of the requested route by using 'route.settings.name' and passing it to my google analytics widget as a custom event (eg "page_clicked", params {"page_name":route.settings.name} – Delmontee Jan 18 '23 at 13:34
  • I saw this answer many times, can you please add a more concrete example? – Xao Feb 27 '23 at 15:00
6

Found the issue. Some of the root routes were built using pageBuilder and NoTransitionPage, so to avoid animation, since they are working as tabs.

But besides setting NoTransitionPage.key initializer argument, you also need to set NoTransitionPage.name for the routes to be recognized.

So, because I did not do that, the navigator saw all these routes as null, so it just didn't see them changing in between.


Example how it should be:

GoRoute(
    name: Routes.home,
    path: Routes.getPathNamed(Routes.home),
    pageBuilder: (context, state) => NoTransitionPage<void>(
      key: state.pageKey, // <--- note this
      name: state.name, // <--- note this
      child: ScaffoldWithBottomBarNav(body: Routes.getPageNamed(Routes.home)),
    ),
  ),
Roman Shirokov
  • 329
  • 4
  • 12