Skip to main content

Capacitor SDK

The official Capacitor SDK for hybrid mobile apps.

Requirements​

  • Capacitor 5+
  • iOS and Android support

Installation​

Use Capacitor SDK 0.5.1 or later for the native storage, initialization, and lifecycle safeguards described below.

npm install @mostly-good-metrics/capacitor@^0.5.1

Required Peer Dependencies​

npm install @capacitor/core @capacitor/app @capacitor/device @capacitor/preferences
npx cap sync

On iOS, the core Capacitor pod has a privacy manifest from 5.7.3 onward. The @capacitor/app, @capacitor/device, and @capacitor/preferences plugins still need app-level declarations. See Apple privacy manifests and App Store labels, including the UserDefaults CA92.1 entry for Preferences.

Quick Start​

Initialize​

Initialize as early as possible in your app:

import MostlyGoodMetrics from '@mostly-good-metrics/capacitor';

MostlyGoodMetrics.configure('mgm_proj_your_api_key', {
appVersion: '1.0.0',
environment: 'production',
});

Track Events​

MostlyGoodMetrics.track('button_clicked', {
button_name: 'signup',
screen: 'home',
});

Identify Users​

MostlyGoodMetrics.identify('user-123');

Super Properties​

Set properties that will be included with every event:

// Set a single super property
MostlyGoodMetrics.setSuperProperty('plan', 'premium');

// Set multiple super properties
MostlyGoodMetrics.setSuperProperties({
plan: 'premium',
tier: 'gold',
});

// Remove a super property
MostlyGoodMetrics.removeSuperProperty('plan');

// Clear all super properties
MostlyGoodMetrics.clearSuperProperties();

Configuration Options​

OptionDefaultDescription
appVersion-App version for install/update tracking
environment'production'Environment name
maxBatchSize100Max events per batch
flushInterval30Seconds between auto-flushes
maxStoredEvents10000Max events to store locally
enableDebugLoggingfalseEnable console logging
trackAppLifecycleEventstrueTrack app open/background events
existingInstallationfalseBaseline lifecycle state on a provider migration without emitting $app_installed
contextProvider-Dynamic properties evaluated for every event
optedOutByDefaultfalseStart opted out until optIn() is called (Privacy)
collectDevicePropertiestrueCollect device properties

Automatic Events​

When trackAppLifecycleEvents is enabled (default):

EventWhen
$app_installedFirst launch after install
$app_updatedFirst launch after app version change
$app_openedApp came to foreground
$app_backgroundedApp went to background

Migration and dynamic context​

For an existing app moving from another provider, derive existingInstallation from that provider's persisted installation marker. Do not set it to true for every user, which would suppress genuine new installs.

MostlyGoodMetrics.configure('mgm_proj_your_api_key', {
existingInstallation: legacyAnalytics.hasInstallationMarker(),
contextProvider: () => ({ active_workspace_id: currentWorkspaceId() }),
});

Dynamic context overrides super properties; explicit event properties and MGM system properties take precedence. With enableDebugLogging, MGM warns when custom properties use reserved $ keys.

Failure handling and teardown​

The SDK uses the JavaScript core with Capacitor storage and lifecycle adapters. Storage failures fall back to memory. Damaged persisted event queues are recovered while valid events are retained, and native listener cleanup handles both thrown errors and rejected removal promises.

Call MostlyGoodMetrics.destroy() when tearing down the SDK. Pending initialization cannot recreate the client or overwrite a later configuration; listeners that finish registering after teardown are removed. flush() handles delivery errors internally and can be awaited to wait for the attempt to finish; resolution does not guarantee server acceptance.

ready(timeoutMs) applies its deadline to native initialization as well as experiment readiness. An unavailable native operation times out after five seconds; later calls use current-process memory for that storage key. Writes are coalesced so a stalled plugin cannot build an unbounded chain. A timed-out write is not canceled by JavaScript, so the SDK avoids issuing newer writes that the old operation could overwrite. This fallback is not durable across process restarts. Unreadable or malformed native consent disables tracking until an explicit optIn() or optOut() choice.

Startup calls and the built-in native event adapter each have a 1 MiB retained data budget in addition to event-count limits. Events can be dropped when those budgets are full or when persisted data is oversized or damaged. Event properties are copied before queuing. Teardown invalidates old adapter work, so a late read or save cannot resurrect an abandoned event queue.

If a native lifecycle listener cannot be removed, its callbacks become inert and the SDK avoids registering more listeners while removal is pending. A late successful removal can resume subscriptions; a failed removal disables further subscriptions for that process. Manual tracking remains available during this lifecycle fallback.

Privacy​

The SDK never collects advertising identifiers, location, or anything you don't explicitly pass to track() or identify(). identify() is optional — without it, users are tracked under a random, resettable anonymous ID ($anon_...).

Opt-out​

MostlyGoodMetrics.optOut();      // stop all tracking immediately
MostlyGoodMetrics.optIn(); // resume tracking
MostlyGoodMetrics.isOptedOut(); // current state

While opted out, tracking calls are no-ops and queued (unsent) events are purged. The SDK attempts to persist the choice in Capacitor Preferences so it survives restarts when native storage is available.

For consent-first apps (e.g. GDPR), start opted out and call optIn() after consent:

MostlyGoodMetrics.configure('mgm_proj_your_api_key', {
optedOutByDefault: true, // no events until optIn() is called
});

A persisted opt-in/opt-out choice always wins over optedOutByDefault on later launches.

Rotating the anonymous ID​

const newId = MostlyGoodMetrics.resetAnonymousId();

Forget me​

resetIdentity() clears the user ID; pass clearAnonymousId: true for a full local reset:

MostlyGoodMetrics.resetIdentity({ clearAnonymousId: true });

This clears the user ID, rotates the anonymous ID, purges pending events and super properties, and starts a new session.

Limiting device properties​

MostlyGoodMetrics.configure('mgm_proj_your_api_key', {
collectDeviceProperties: false,
});

The JS core's respectDoNotTrack and persistence options are web-only and are not part of the Capacitor configuration.

Manual Flush​

MostlyGoodMetrics.flush();

Platform Support​

  • iOS
  • Android
  • Web (with limited lifecycle tracking)