Skip to main content

Introduction

Flutter Web release builds are compiled to minified JavaScript, so a stack trace from a real user looks like this:
When you upload your build’s source maps to Lerix, the dashboard maps each frame back to your Dart code, for example lib/chat/chat_store.dart:15, with the Dart member name. The maps are uploaded privately and deleted from your build output before you deploy. They are never served publicly, so your source code stays private.
Complete the Flutter installation first. Web stack traces require lerix_flutter 0.0.2 or newer.
Source maps are only needed for Flutter Web. Android and iOS release builds already report Dart file and line numbers, see Mobile builds.

1. Build with source maps

Add --source-maps to your web build:
Check that main.dart.js.map appears next to main.dart.js in build/web.

2. Create a private API key

Uploading source maps needs a private key, separate from the public project key your app uses.
  1. Open your project in the Lerix Dashboard.
  2. Go to Project settings → API keys.
  3. Create a key with the Upload source maps permission (or Full access).
This key is secret. Store it as a CI secret and never put it in client code or commit it to your repository.

3. Upload the maps after each build

After flutter build web --source-maps and before you deploy, run the Lerix CLI:
Run it from your Flutter project folder. It finds build/web on its own and uses the version from pubspec.yaml, without the +build number, as the release. For version: 1.4.0+12, the release is 1.4.0. The CLI uploads the .map files, then deletes them from build/web so they are never deployed. If any upload fails, it keeps the maps and exits with code 1, so you can retry the step. The CLI requires Node.js 18.17 or newer.
Upload after every build. main.dart.js keeps the same name across builds, so the release is what tells builds apart. Bump version in pubspec.yaml for each release.

Options

Each option can also be set with an environment variable.

4. Nothing to pass to the SDK

The Flutter SDK reports the same release on its own: the version from pubspec.yaml, without the +build number. You don’t need to set a release in Lerix.init().

Example: GitHub Actions

This workflow builds the web app, uploads the maps, then deploys. Add LERIX_API_KEY, LERIX_PROJECT_ID and LERIX_SECRET_KEY as repository secrets.
.github/workflows/deploy.yml

What you see in the dashboard

New web errors show the original Dart file, line and member name. Flutter framework frames appear as package:flutter/... and are dimmed as library code. The AI assistant, GitHub issues and the MCP server all receive the readable stack too.
  • dart2js source maps don’t embed your source code, so web errors show the file and line without a code snippet.
  • Only errors reported after the maps are uploaded are mapped. Earlier errors keep their minified stack.

Mobile builds

Android and iOS release builds already report Dart file and line numbers. No setup is needed. Builds made with --obfuscate --split-debug-info are not symbolicated yet.

Troubleshooting