Skip to content
Codeskop

Flutter

The codeskop_tracker plugin captures errors from your Dart code and passes them to the native Codeskop SDK, which also catches native crashes and ANRs underneath Flutter.

Requirements

  • Flutter 3.19 or later, Dart 3.3 or later
  • Android minSdk 24 or higher
  • A public ingest key from the Codeskop dashboard
  1. Add the plugin

    Add it to pubspec.yaml, then run flutter pub get.

    pubspec.yaml
    dependencies:  codeskop_tracker: ^0.3.0

    The plugin brings in the native Android SDK for you. Don't add tracker-android to your Gradle files separately.

  2. Initialize and wrap your app

    Call Codeskop.runGuarded once, around runApp.

    lib/main.dart
    import 'package:codeskop_tracker/codeskop_tracker.dart';import 'package:flutter/material.dart'; void main() {  Codeskop.runGuarded(() async {    await Codeskop.init(      apiKey: 'cs_live_pk_YOUR_KEY',      endpoint: 'https://api.codeskop.com',    );    runApp(const MyApp());  });}

    runGuarded calls WidgetsFlutterBinding.ensureInitialized() and sets up every Dart error hook for you: FlutterError.onError, PlatformDispatcher.onError, and a guarded zone for uncaught async errors. Flutter's usual red error screen and console output still work.

  3. Identify your users

    Optional, but recommended.

    Dart
    // After loginawait Codeskop.identify(user.id, traits: {'plan': user.plan}); // On logoutawait Codeskop.reset();

    Use your own stable user ID, never an email. As on native Android, call identify again when the app restarts with a signed-in user. See Identify users.

What's captured automatically

  • Uncaught Dart errors, reported as crashes, with the Dart stack trace
  • Errors reported by the Flutter framework, reported as handled exceptions
  • Native crashes and ANRs in the Android layer, from the native SDK (see Crash reporting and ANR monitoring)

Product analytics

On Growth and Scale, record screens and events for funnels, retention and segments. Add the navigator observer so named routes become screens, and track what matters:

Dart
MaterialApp(navigatorObservers: [CodeskopNavigatorObserver()], ...); await Codeskop.track('order_completed', properties: {'value': 49.99, 'currency': 'KES'});

See Track events & screens.

Report handled errors

Dart
try {  await checkout();} catch (e, stack) {  Codeskop.recordError(e, stack);   // reported as a handled exception  showErrorBanner();}

Report failed HTTP calls

The plugin doesn't include an HTTP interceptor. Instead, call Codeskop.captureApiError from your own. With Dio, it looks like this:

lib/network/codeskop_dio_interceptor.dart
import 'package:codeskop_tracker/codeskop_tracker.dart';import 'package:dio/dio.dart'; class CodeskopDioInterceptor extends Interceptor {  @override  void onError(DioException err, ErrorInterceptorHandler handler) {    Codeskop.captureApiError(      method: err.requestOptions.method,      url: err.requestOptions.uri.toString(),      status: err.response?.statusCode,      errorKind: err.response == null ? 'network_error' : null,    );    handler.next(err);  }} final dio = Dio()..interceptors.add(CodeskopDioInterceptor());

Query strings are removed from the URL before it's stored. Optional requestBytes and responseBytes arguments record payload sizes.

Advanced

Managing the zone yourself

If you already run your app in your own runZonedGuarded, call registerErrorHooks() instead of runGuarded, and forward zone errors to recordError:

lib/main.dart
void main() {  runZonedGuarded(() async {    WidgetsFlutterBinding.ensureInitialized();    Codeskop.registerErrorHooks();    await Codeskop.init(apiKey: 'cs_live_pk_YOUR_KEY', endpoint: 'https://api.codeskop.com');    runApp(const MyApp());  }, (error, stack) => Codeskop.recordError(error, stack, fatal: true));}

Configuration on Flutter

In version 0.3.0, the Flutter API takes only apiKey and endpoint. Everything else uses the native SDK's defaults and remote config.

Next steps