Screen Tagging
Screen Tagging in Flutter Mobile
Good screen names turn raw replays into actionable heat‑maps, screen analytics, conversion funnels and journey charts. This guide walks you through reviewing the automatic tags first, deciding when (and how) to add manual tags, and finally verifying that every screen shows up with a meaningful duration.
Which Approach Should I Use?For most Flutter apps, use the
FlutterUxcamNavigatorObserverwithenableAutomaticScreenNameTagging: false. The Navigator Observer tracks Flutter route changes accurately, while automatic screen name tagging is designed for native UIKit/Activity hierarchies and may not reflect Flutter navigation correctly.
Approach Best For Config Navigator Observer (recommended) Most Flutter apps using NavigatororGoRouterenableAutomaticScreenNameTagging: false+ addFlutterUxcamNavigatorObserverAutomatic Tagging Apps with heavy native screens or platform views enableAutomaticScreenNameTagging: true(default)Manual Tagging Complex navigation or custom route systems Call FlutterUxcam.tagScreenName('ScreenName')explicitly
Screen Tagging in Flutter
Flutter's architecture requires a different approach to screen tagging compared to native frameworks. You have two options:
Tagging Methods Available
| Tagging Method | Flutter Support | Best For | Configuration |
|---|---|---|---|
| Navigation Observer | ✅ Semi-automatic - captures route names | Apps using Navigator 1.0 or 2.0 with named routes | Add FlutterUxcamNavigatorObserver |
| Manual Screen Tagging | ✅ Fully supported and most reliable | All apps, especially those with complex navigation | Call FlutterUxcam.tagScreenName() |
Important
Navigation Observer limitations: Currently does not support Bottom Navigation or Tab Navigation when using Navigator 1.0 or 2.0. For these cases, use manual tagging.
Option 1: Semi-Automatic with Navigation Observer (Recommended Starting Point)
While native frameworks may offer automatic tagging, in Flutter, the architecture requires using a Navigation Observer or manual tagging to ensure all screens are clearly and consistently identified in your analytics. This approach gives you full control over how each screen is represented, leading to more accurate and meaningful insights.
Important:Flutter UXCam SDK version 2.2.2 introduces the option to add tagging from the Flutter side of your app. This feature is optional and still under active development, so any feedback during testing is highly appreciated.
Note: This feature currently does not support Bottom Navigation or Tab Navigation for tagging when using Navigator 1.0 or 2.0. However, ongoing work on Navigator 2.0 aims to address these issues in the future.
Adding FlutterUxcamNavigatorObserver to Your App:
FlutterUxcamNavigatorObserver to Your App:From FlutterUXCam SDK version 2.2.2, you can add a FlutterUxcamNavigatorObserver to your app, enabling automatic capture of your routes (screens) for screen tagging without requiring manual intervention.
Steps to Integrate FlutterUxcamNavigatorObserver:
- Import the SDK:
In your Dart file, import theflutter_uxcampackage:
import 'package:flutter_uxcam/flutter_uxcam.dart'; - Disable Automatic Screen Name Tagging
Ensure the configuration parameterenableAutomaticScreenNameTaggingis set tofalse. - Add the Navigation Observer
- Using Navigator 1.0:\
Add theFlutterUxcamNavigatorObserverto thenavigatorObserversof your `MaterialAppMaterialApp( ... navigatorObservers: [ FlutterUxcamNavigatorObserver(), ], ... ) - Using Navigator 2.0:\
Add it to the observers for your router. Below is an example using GoRouter:final GoRouter router = GoRouter( ... observers: [ FlutterUxcamNavigatorObserver(), ], ... );
- Using Navigator 1.0:\
- Add Names to Your Routes\
It is recommended to add names to your routes to ensure clear tagging. If no names are provided, routes may show up as default values such as '/'.
Additional Considerations for Flutter
Navigation Events: If you're using a navigation package like flutter_bloc or provider, ensure that screen tagging is part of the navigation logic. This guarantees that every screen transition is tracked properly.
Consistent Naming: Be consistent with your screen names across the app. This will make analyzing data in the UXCam dashboard more intuitive and prevent confusion.
Handling Bottom Navigation and Tab Navigation
Important Limitation: The automatic tagging feature currently does not support Bottom Navigation or Tab Navigation for tagging when using Navigator 1.0 or 2.0. These scenarios require manual tagging for accurate analytics.
Why Manual Tagging is Needed for Navigation Bars
When using BottomNavigationBar or TabBar, the automatic tagging may only capture the parent screen name (e.g., "MainScreen") rather than the specific tab content (e.g., "Home Tab", "Profile Tab"). This can lead to:
- Incomplete user journey tracking: All tab interactions appear under one screen name
- Missing heatmap data: User interactions are aggregated incorrectly
- Poor funnel analysis: Cannot distinguish between different tab content
Hybrid Approach: Automatic + Manual Tagging
The best practice is to use automatic tagging for your main navigation flow and supplement it with manual tagging for navigation bars. Here's how to implement this:
Example 1: Bottom Navigation with Manual Tab Tagging
import 'package:flutter/material.dart';
import 'package:flutter_uxcam/flutter_uxcam.dart';
class MainScreen extends StatefulWidget {
@override
_MainScreenState createState() => _MainScreenState();
}
class _MainScreenState extends State<MainScreen> {
int _currentIndex = 0;
final List<Widget> _screens = [
HomeTab(),
ProfileTab(),
SettingsTab(),
];
@override
Widget build(BuildContext context) {
return Scaffold(
body: _screens[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
currentIndex: _currentIndex,
onTap: (index) {
setState(() {
_currentIndex = index;
});
// Manual tagging for tab changes
switch (index) {
case 0:
FlutterUxcam.tagScreenName("Home Tab");
break;
case 1:
FlutterUxcam.tagScreenName("Profile Tab");
break;
case 2:
FlutterUxcam.tagScreenName("Settings Tab");
break;
}
},
items: [
BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
BottomNavigationBarItem(icon: Icon(Icons.person), label: 'Profile'),
BottomNavigationBarItem(icon: Icon(Icons.settings), label: 'Settings'),
],
),
);
}
}Example 2: TabBar with Manual Tab Tagging
import 'package:flutter/material.dart';
import 'package:flutter_uxcam/flutter_uxcam.dart';
class TabScreen extends StatefulWidget {
@override
_TabScreenState createState() => _TabScreenState();
}
class _TabScreenState extends State<TabScreen> with SingleTickerProviderStateMixin {
late TabController _tabController;
@override
void initState() {
super.initState();
_tabController = TabController(length: 3, vsync: this);
// Listen to tab changes for manual tagging
_tabController.addListener(() {
if (!_tabController.indexIsChanging) {
_tagCurrentTab();
}
});
// Tag initial tab
_tagCurrentTab();
}
void _tagCurrentTab() {
switch (_tabController.index) {
case 0:
FlutterUxcam.tagScreenName("Products Tab");
break;
case 1:
FlutterUxcam.tagScreenName("Orders Tab");
break;
case 2:
FlutterUxcam.tagScreenName("Analytics Tab");
break;
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Dashboard'),
bottom: TabBar(
controller: _tabController,
tabs: [
Tab(text: 'Products'),
Tab(text: 'Orders'),
Tab(text: 'Analytics'),
],
),
),
body: TabBarView(
controller: _tabController,
children: [
ProductsTab(),
OrdersTab(),
AnalyticsTab(),
],
),
);
}
@override
void dispose() {
_tabController.dispose();
super.dispose();
}
}Example 3: GoRouter with Bottom Navigation
import 'package:flutter/material.dart';
import 'package:flutter_uxcam/flutter_uxcam.dart';
import 'package:go_router/go_router.dart';
class AppWithBottomNav extends StatefulWidget {
@override
_AppWithBottomNavState createState() => _AppWithBottomNavState();
}
class _AppWithBottomNavState extends State<AppWithBottomNav> {
int _currentIndex = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
body: IndexedStack(
index: _currentIndex,
children: [
HomeScreen(),
ProfileScreen(),
SettingsScreen(),
],
),
bottomNavigationBar: BottomNavigationBar(
currentIndex: _currentIndex,
onTap: (index) {
setState(() {
_currentIndex = index;
});
// Manual tagging for navigation changes
_tagNavigationChange(index);
},
items: [
BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
BottomNavigationBarItem(icon: Icon(Icons.person), label: 'Profile'),
BottomNavigationBarItem(icon: Icon(Icons.settings), label: 'Settings'),
],
),
);
}
void _tagNavigationChange(int index) {
final String screenName = switch (index) {
0 => "Home Screen",
1 => "Profile Screen",
2 => "Settings Screen",
_ => "Unknown Screen"
};
FlutterUxcam.tagScreenName(screenName);
}
}Best Practices for Hybrid Tagging
- Keep Automatic Tagging Enabled: Let the
FlutterUxcamNavigatorObserverhandle your main navigation flow - Manual Tagging for Navigation Bars: Add manual tags in navigation change callbacks
- Consistent Naming Convention: Use descriptive names like "Home Tab" or "Profile Screen"
- Avoid Duplicate Tags: Ensure manual tags don't conflict with automatic ones
- Test Thoroughly: Verify that both automatic and manual tags appear correctly in your dashboard
Verification Checklist
After implementing hybrid tagging, verify:
- Main navigation flows are captured automatically
- Tab/bottom navigation changes are tagged manually
- No duplicate screen names appear in the dashboard
- Each tab/screen has meaningful duration (> 0s)
- Screen names are consistent with your analytics terminology
Tip
This hybrid approach gives you the best of both worlds: automatic tagging for simplicity and manual tagging for precision where needed.
Manual Screen Tagging - For In Depth Customisation
IMPORTANT: Please make sure to set
enableAutomaticScreenNameTagging:falsefor better results
Tagging a Screen Manually: One Simple Line of Code:
In Flutter, tagging a screen manually is straightforward. You can use the following line of code to tag a screen:
import 'package:flutter_uxcam/flutter_uxcam.dart';
FlutterUxcam.tagScreenName("Home Screen");Example: The Recommended Place to Tag
To ensure your screens are tagged consistently, we recommend placing the tagging code inside the initState() method of your widget or using a navigation listener to call the screen tagging method every time the screen appears.
import 'package:flutter/material.dart';
import 'package:flutter_uxcam/flutter_uxcam.dart';
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
@override
void initState() {
super.initState();
FlutterUxcam.tagScreenName("Home Screen");
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Home Screen"),
),
body: Center(
child: Text("Welcome to the Home Screen!"),
),
);
}
}This approach ensures that every time a user navigates back to this screen, it's correctly tagged in your analytics.
Summary:
- Automatic Tagging Should be Off: Due to how Flutter manages navigation, automatic tagging may not always be reliable.
- Manual Tagging: Use lifecycle methods like initState() or navigation listeners to tag screens accurately every time they are shown.
By taking this approach, you can make data-driven decisions and gain actionable insights into how users navigate through your app.
Verify Your Tags
So you've decided to manually tag some or all your screens, making sure this is properly set up is a fundamental part in ensuring heat-maps, funnels and user journey analytics is giving you full insights, so it is extremely important to verify everything works well before moving on:
-
In your debug environment, run the app and visit all the manually tagged screens, then background the app.
-
Once the session uploads, check:
- Each screen appears exactly once, according to the user's navigation, with duration > 0 s.
- No “Unknown” or class‑name (if fully manual) screens remain.
- Names match your analytics language.
If something is off, look for duplicate tag calls or a missing route handler.
Important
Having a solid screen tagging setup will make masking PII Data and occluding screens extremely easier.
Troubleshooting cheat‑sheet
| Issue | Quick diagnosis | Solution |
|---|---|---|
| 0 s screens | Duplicate tag same frame (auto + manual) | Disable auto tagging or remove extra tag |
| Screen missing | NavController route not handled | Add case in when(route) |
| Random class names | Forgot to rename in Dashboard | Edit in Screens tab |
| Stale name after refactor | Hard‑coded tag string | Update FlutterUxcam.tagScreenName() constant |
How to Tag WebViews
WebViews can be a unique challenge when it comes to screen tagging, as they often contain dynamic content. To properly tag your WebView screens, you can follow our detailed guide that walks you through the best practices and methods for effective WebView tagging.
For more information, click the button below:
[Tagging WebViews Documentation](/docs/ALL UXCAM APIs/tag-of-screens/web-view-tagging)
Next Steps:
You've properly tagged screens and are ready to move on! Let's review some next steps you should take.
Updated 11 days ago
