Analytics
XWidget automatically collects analytics when the Resources instance passed to
XWidget.initialize() has a projectKey configured — either CloudResources(...)
or LocalResources.withAnalytics(...). No manual instrumentation is required —
renders, downloads, errors, and navigation transitions are tracked out of the box.
Automatic Tracking
The SDK tracks four types of events:
Render Events
Every time a fragment is inflated and rendered, a render event is recorded with the fragment name. If the render fails, an error count is recorded instead. This happens automatically inside XWidget's rendering pipeline.
Download Events
When loading resources from XWidget Cloud, the SDK tracks each bundle load. Events distinguish between fresh downloads, cache hits (the channel pointer was unchanged or still named the cached revision), and errors. This is tracked automatically during resource loading.
Error Events
When a fragment render or bundle download fails, a detailed error event is recorded with the error message (truncated to 512 characters). Unique error messages are capped at 50 per persist cycle to prevent error storms from flooding storage.
Navigation Transitions
The SDK automatically injects an AnalyticsNavigatorObserver into your app's
MaterialApp, CupertinoApp, or Navigator widget. This observer tracks push, pop,
and replace navigation actions using the route name from RouteSettings.name.
Note
The observer is injected automatically when XWidget inflates a MaterialApp,
CupertinoApp, WidgetsApp, or Navigator from XML. You do not need to add
it manually. If you're building your app widget in Dart (not XML), you can add
it yourself:
How It Works
The analytics pipeline operates in three stages:
Memory → Storage → Server
-
Capture — Events are aggregated in memory using dimension-based keys (channel, version, platform, locale, fragment name, etc.). Identical dimensions are merged by incrementing counters rather than creating duplicate entries.
-
Persist — Every 10 seconds, the in-memory buffer is written to local storage and cleared. Events are split by type (render, download, error) into separate files. If the write fails, events are returned to the memory buffer for retry.
-
Flush — Every 15 minutes, persisted files are re-aggregated across files, sent to the XWidget Cloud analytics server, and deleted on success. Each event type is sent independently — a failed download flush does not block render or error events.
On app pause or close, the SDK persists any in-memory events and attempts a final flush. Unsent files from previous sessions are flushed on the next app launch. Files older than 72 hours are automatically discarded.
Sessions
The SDK maintains a session for navigation tracking. Each session has a unique 32-character ID and a sequence counter that increments with each navigation event. Sessions expire after 15 minutes of inactivity, at which point a new session begins.
Event Dimensions
Every event includes these base dimensions, attached automatically:
| Dimension | Source |
|---|---|
| Channel | From the Resources provider — explicit on CloudResources, always 'local' for LocalResources.withAnalytics |
| Version | The full version string passed to the Resources provider, including any +N build number |
| Revision | The deployment revision the app is running, learned from the channel pointer. Reported as unknown until the first successful cloud load, and always unknown for local resources |
| Platform | Auto-detected (android, ios, linux, macos, windows, web) |
| Locale | Country code from the device's locale setting |
Events are also tagged with Country, a separate dimension derived by the
analytics server. Locale and country can differ — for example, a phone set to
en-US used in France reports US for locale and FR for country.
Render and error events also include the fragment name. Error events include the error message.
Querying Analytics
Analytics data is queried through the CLI, not the SDK. See:
Disabling Analytics
Analytics are only enabled when the Resources instance passed to
XWidget.initialize() has a projectKey configured — that is,
CloudResources(...) or LocalResources.withAnalytics(...). The default
LocalResources() has no projectKey, so no analytics are collected and no
network requests are made.
// No analytics — default local resources
await XWidget.initialize(register: registerXWidgetComponents);
Shutdown
Analytics starts when the Resources provider activates and flushes automatically
on app pause or close. If you need to shut down manually:
This persists any remaining in-memory events and attempts a final flush to the server.