Flutter
Add the replicate_interceptor package to your Flutter app to enable recording and intercept mode.
ReplicateInterceptor.init() is a no-op in release builds. It is safe to leave in your production code — it will never intercept network calls in a release build.
Installation #
Add the package to your pubspec.yaml. View it on pub.dev.
dependencies:
replicate_interceptor: ^0.1.0
Then fetch dependencies:
flutter pub get
cd ios && pod install # if targeting iOS
Setup #
Call ReplicateInterceptor.init() as the very first thing in main(), before runApp() and before any network calls:
// main.dart — before everything else
import 'package:replicate_interceptor/replicate_interceptor.dart';
void main() async {{
WidgetsFlutterBinding.ensureInitialized();
await ReplicateInterceptor.init();
runApp(const MyApp());
}}
init() must be called after WidgetsFlutterBinding.ensureInitialized() but before runApp(). Any network calls that happen before init() resolves will not be captured.
How it works #
The interceptor reads a session config file that Replicate writes into your simulator app's Documents directory before launching. If the file is absent (normal development, CI), the interceptor stays inactive and has zero overhead.
Based on the mode in the session config, the interceptor either records, intercepts, or simply restores keychain state:
Session config reference #
Replicate writes this file to <AppContainer>/Documents/replicate_session.json before launching your app:
{
"sessionId": "uuid",
"mode": "record | intercept | dump_keystore | restore_only",
"restoreKeystore": false
}
Modes #
| Mode | What it does |
|---|---|
record | Intercepts all HTTP calls, writes tape files + keystore dump to Documents |
intercept | Loads override files, modifies requests/responses per your rules; manual tape entries are served locally |
dump_keystore | Exports flutter_secure_storage entries to a JSON file, then stays inactive |
restore_only | Restores keystore entries from file, then stays inactive with no network interception |
Tape file format #
Each recorded request is saved as a separate JSON file in Documents/replicate_tape/<uuid>.json:
{
"id": "uuid",
"method": "GET",
"url": "https://api.example.com/v1/cart",
"requestHeaders": {{}},
"requestBody": null,
"requestBodyEncoding": "utf8",
"statusCode": 200,
"responseHeaders": {{}},
"responseBody": "{...}",
"responseBodyEncoding": "utf8",
"timestamp": "2026-01-01T00:00:00Z",
"durationMs": 142,
"isSuccess": true,
"source": "record"
}
application/json, text/*, application/xml) are stored as utf8. Binary content (images, multipart uploads, protobuf) is stored as base64 with the encoding field set to "base64".
Keystore format #
Keychain entries from flutter_secure_storage are exported as a flat key–value map:
{
"entries": {{
"access_token": "eyJhbGci...",
"user_id": "12345"
}}
}}
Troubleshooting #
| Symptom | Solution |
|---|---|
| Interceptor not recording | Make sure init() is called before runApp(). Confirm that Replicate has started a recording session before launching the app. |
| Works in debug but not release | Expected — the interceptor is a no-op in release builds by design. |
| Keystore not captured | Only flutter_secure_storage is supported. Other storage libraries are not captured. |
| Network calls missing from tape | Calls made before init() completes will not be captured. Move init() earlier in main(). |