SDK & Framework Guides

Error Tracking for Ionic & Capacitor

Get full-stack Ionic Capacitor error tracking for production apps—native crashes, source maps, release health, and distributed tracing.

Production apps built with Ionic and Capacitor face a unique challenge: hybrid apps combine web code with native layers, and crashes can originate from either side. When a user's app crashes on iOS or Android, you need the full context — JavaScript stack traces, native exceptions, breadcrumbs, and affected-user counts. Ionic Capacitor error tracking production apps demands a monitoring solution that bridges both worlds, captures source maps to de-minify your builds, and tracks health across releases.

LightTrace is Sentry-SDK-compatible, meaning you can point any unmodified Sentry SDK at LightTrace and get error tracking, distributed tracing, and release health monitoring in minutes. For Ionic and Capacitor, that means the same setup you'd use for web or native apps, but without building around limitations of free services or juggling multiple platforms.

Set up the Sentry SDK for Ionic & Capacitor

Start with the JavaScript SDK. Install it in your Ionic project:

npm install @sentry/react-native
# or yarn add @sentry/react-native

If you're using plain React with Capacitor, use @sentry/react (or @sentry/angular for Angular, @sentry/vue for Vue). The React Native SDK includes platform-specific integrations that hook into Capacitor's native layers and capture crashes from Objective-C, Swift, Kotlin, and Java code.

Initialize Sentry early in your app, before any other imports. In a typical Ionic React app:

// main.tsx
import * as Sentry from "@sentry/react-native";

Sentry.init({
  dsn: "https://<your-key>@light-trace.robomiri.com/1",
  environment: "production",
  release: "1.2.0",
  tracesSampleRate: 0.1, // Capture 10% of transactions for tracing
  integrations: [
    new Sentry.ReactNativeIntegration(),
    new Sentry.NativeLinkerIntegration(),
  ],
});

export default Sentry.wrap(App);

The dsn is your LightTrace endpoint — replace <your-key> and light-trace.robomiri.com with your credentials. The release version ties errors to your CI/CD pipeline, enabling how-to-debug-production-errors efficiently. The integrations array enables native crash capture from Capacitor plugins.

Set environment: "production" only in your production build. Use "staging" or "development" in test builds so you can filter errors by deployment stage in the dashboard.

Capture native crashes and Capacitor plugin errors

Capacitor plugins often wrap native code. When a plugin crashes—say, a camera permission error or a geolocation failure—the error can originate in native code or be surfaced through the JavaScript layer. The NativeLinkerIntegration in Sentry ensures that both JavaScript exceptions and native crashes are sent to LightTrace.

For explicit error handling, wrap Capacitor calls with Sentry context:

import { Capacitor } from "@capacitor/core";
import { Camera, CameraResultType } from "@capacitor/camera";
import * as Sentry from "@sentry/react-native";

async function capturePhoto() {
  try {
    const image = await Camera.getPhoto({
      quality: 90,
      allowEditing: true,
      resultType: CameraResultType.Uri,
    });
    return image;
  } catch (error) {
    Sentry.captureException(error, {
      tags: {
        plugin: "camera",
        platform: Capacitor.getPlatform(),
      },
      contexts: {
        capacitor: {
          platform: Capacitor.getPlatform(),
        },
      },
    });
    throw error;
  }
}

This approach ensures that if the camera plugin fails on iOS but not Android, you'll see that breakdown in LightTrace's dashboard. Tags and contexts make it easy to filter issues by platform, plugin, or user segment.

Configure source maps for minified builds

Ionic builds are minified and bundled for production. Without source maps, your stack traces in LightTrace will show line numbers in bundled code—useless for debugging. Upload source maps to LightTrace so that every error is de-minified back to your original code.

First, generate source maps in your Ionic build:

ionic build --prod --source-map

Then use the Sentry CLI to upload them to LightTrace:

npm install --save-dev @sentry/cli

Create a .sentryclirc file in your project root:

[auth]
token=<your-sentry-cli-token>

[defaults]
url=https://light-trace.robomiri.com
org=your-org
project=your-project

Run the upload after each build (or integrate it into your CI/CD):

sentry-cli releases files upload-sourcemaps \
  --release=1.2.0 \
  ./build

Now every JavaScript error will show your original source code, not minified gibberish. You can click a stack frame and jump to the exact line on GitHub if your LightTrace instance is linked to your GitHub org.

Track release health and crash-free sessions

LightTrace tracks crashes-free metrics for each release. When you set the release field during initialization, LightTrace automatically counts users and sessions, and calculates the percentage of sessions that completed without a crash.

Sentry.init({
  dsn: "https://<your-key>@light-trace.robomiri.com/1",
  release: "1.2.0",
  // Sentry automatically tracks session health
});

In the dashboard, navigate to Releases and view the crash-free percentage for each version. If a rollout drops your crash-free rate below a threshold, you can set up alert rules to notify your team via email. Release tracking is essential for mobile apps because users hold app versions for weeks or months; you need to know if a version is stable before promoting it to general availability.

LightTrace alerts are delivered by email and can be triggered on new issue creation or event frequency thresholds. Set up an alert rule for crash-free rate < 95% to catch regressions early.

Breadcrumbs are automatic records of user interactions (taps, navigation, network requests) that led to an error. Sentry SDKs capture them for free; LightTrace stores and displays them alongside the error.

To log custom breadcrumbs:

import * as Sentry from "@sentry/react-native";

function onCheckout() {
  Sentry.captureMessage("Checkout initiated", "info");
  Sentry.addBreadcrumb({
    category: "checkout",
    message: "User clicked checkout button",
    level: "info",
    timestamp: Date.now() / 1000,
  });

  // Perform checkout logic
  completeTransaction();
}

When a checkout error occurs later, you'll see the breadcrumb chain showing that the user tapped checkout—giving you context to reproduce the issue. For mobile apps, this is crucial because you often can't attach a session replay; breadcrumbs are your audit trail.

Monitor performance with distributed tracing

If your Ionic app calls a backend API, use transactions to trace the round-trip time. This helps you spot slow endpoints that frustrate users:

import * as Sentry from "@sentry/react-native";

async function fetchUserData(userId) {
  const transaction = Sentry.startTransaction({
    name: "Fetch User Data",
    op: "http.client",
  });

  const span = transaction.startChild({
    op: "http.request",
    description: `GET /api/users/${userId}`,
  });

  try {
    const response = await fetch(`https://api.example.com/users/${userId}`);
    const data = await response.json();
    span.setStatus("ok");
    return data;
  } catch (error) {
    span.setStatus("error");
    Sentry.captureException(error);
    throw error;
  } finally {
    span.finish();
    transaction.finish();
  }
}

LightTrace stores transaction p50, p75, p95, and p99 latencies, plus throughput and error rate, so you can see which API calls are slow or unreliable. If a new version of your app introduces a regression, you'll spot it in the Performance section immediately.

Best practices for Ionic Capacitor monitoring

Disable error tracking in development. Set enabled: false locally or use environment detection:

Sentry.init({
  dsn: process.env.NODE_ENV === "production" 
    ? "https://<your-key>@light-trace.robomiri.com/1" 
    : undefined,
});

Scrub sensitive data. Configure the beforeSend hook to redact PII:

Sentry.init({
  beforeSend(event) {
    if (event.request) {
      delete event.request.cookies;
      delete event.request.headers["Authorization"];
    }
    return event;
  },
});

Test error capture locally. Use Sentry's test integration:

import { TestIntegration } from "@sentry/react-native";

Sentry.init({
  integrations: [new TestIntegration({ logErrors: true })],
});

Throw an error and verify it appears in LightTrace before shipping.

Never hard-code API keys in your app source. Use environment variables in your build pipeline, or fetch the DSN from a config endpoint during app startup.

Alternatives and comparison

If you're comparing solutions, understand what each offers. Firebase Crashlytics is free but lacks distributed tracing and performance monitoring—you get crashes but not the full context of slow endpoints or multi-service failures. Browser error tracking solutions like Rollbar or Datadog are web-first and don't integrate as cleanly with Capacitor's native layers. LightTrace is Sentry-SDK-compatible, so your mobile monitoring setup mirrors your add-error-tracking-to-your-app approach for web, Python, Node.js, or other runtimes—one familiar API across your entire platform.

Getting production error tracking running on Ionic and Capacitor takes less than an hour. Initialize the SDK, upload source maps, and you're monitoring JavaScript errors, native crashes, release health, and performance. Your team can now debug production issues with full context instead of hunting through logs or waiting for user reports.

Start tracking errors in minutes

Start monitoring your Ionic and Capacitor app for free with LightTrace—5,000 events/month, no credit card required. Set up error tracking, release health, and distributed tracing in minutes.

Fix your next production error faster

Point any Sentry SDK at LightTrace — free up to 5,000 events/month.