EasyStarter logoEasyStarter

Analytics

Configure OpenPanel and track only key funnel events

Analytics

The mobile app uses OpenPanel for analytics — open-source, privacy-friendly, self-hostable. When no Client ID or Client Secret is set, the SDK skips initialization entirely.

The mobile template does not listen to every route change by default. Track only key funnel steps such as onboarding completed, login succeeded, subscription started, core generation finished, and submission created. This keeps the data useful and avoids spending free-tier usage on low-signal navigation events.

Create an OpenPanel project

Official docs: React Native SDK

  1. Sign up at openpanel.dev
  2. In the dashboard click Create Project
  3. Fill in Project name (feel free to reuse the same project as Web for cross-platform funnels)
  4. Enable App, and turn off Website and Backend / API unless you need them now
  5. Click Create project
  6. After creation, copy the App Client ID and Client Secret from the project's client details

Set environment variables

Local development (apps/native/.env.development.local):

Loaded by expo start in dev mode. Stays on your machine — never bundled into a release artifact:

apps/native/.env.development.local
EXPO_PUBLIC_OPENPANEL_CLIENT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
EXPO_PUBLIC_OPENPANEL_CLIENT_SECRET=xxxxxxxx-client-secret

Local production builds (apps/native/.env.production):

When you build in production mode locally — e.g. eas build --local --profile production, a native build after expo prebuild, or expo export for an OTA bundle — Expo loads this file automatically based on NODE_ENV=production. Start by copying the example:

cp apps/native/.env.production.example apps/native/.env.production

Then fill in the Client ID and Client Secret:

apps/native/.env.production
EXPO_PUBLIC_OPENPANEL_CLIENT_ID=xxxxxxxx-prod-client-id
EXPO_PUBLIC_OPENPANEL_CLIENT_SECRET=xxxxxxxx-prod-client-secret

.env.production is gitignored and stays local. For EAS cloud builds, eas.json's env block takes precedence and overrides any variable defined in this file — cloud builds only need the configuration below.

Cloud builds (env block in apps/native/eas.json):

eas.json defines three build profiles (development, preview, production), each with its own env block. Fill in a Client ID and Client Secret per profile. If you want to keep production data separate from internal builds, create different Clients in the OpenPanel dashboard for each environment rather than reusing one — otherwise events from QA builds and real users land in the same project.

apps/native/eas.json
{
  "build": {
    "development": {
      "developmentClient": true,
      "distribution": "internal",
      "env": {
        // ...
        "EXPO_PUBLIC_OPENPANEL_CLIENT_ID": "xxxxxxxx-dev-client-id",
        "EXPO_PUBLIC_OPENPANEL_CLIENT_SECRET": "xxxxxxxx-dev-client-secret"
      }
    },
    "preview": {
      "distribution": "internal",
      "channel": "preview",
      "env": {
        // ...
        "EXPO_PUBLIC_OPENPANEL_CLIENT_ID": "xxxxxxxx-preview-client-id",
        "EXPO_PUBLIC_OPENPANEL_CLIENT_SECRET": "xxxxxxxx-preview-client-secret"
      }
    },
    "production": {
      "autoIncrement": true,
      "channel": "production",
      "env": {
        // ...
        "EXPO_PUBLIC_OPENPANEL_CLIENT_ID": "xxxxxxxx-prod-client-id",
        "EXPO_PUBLIC_OPENPANEL_CLIENT_SECRET": "xxxxxxxx-prod-client-secret"
      }
    }
  }
}

Track key events explicitly

The native app exposes explicit tracking helpers. Call them only at meaningful product milestones:

import { trackOpenPanelEvent } from "@/lib/analytics/openpanel";

trackOpenPanelEvent("onboarding_completed", {
  source: "welcome_flow",
});

If a screen is part of the funnel, record a screen view manually:

import { trackOpenPanelScreenView } from "@/lib/analytics/openpanel";

trackOpenPanelScreenView("/paywall");

Do not listen to every route change by default. Start with 3-5 key funnel steps, then add events only when they answer a real product question.