Skip to content

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.

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:

MaterialApp(
  navigatorObservers: [AnalyticsNavigatorObserver()],
)

How It Works

The analytics pipeline operates in three stages:

Memory → Storage → Server

  1. 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.

  2. 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.

  3. 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:

await Analytics.shutdown();

This persists any remaining in-memory events and attempts a final flush to the server.