Flutter SDK
Complete integration guide for the Encatch Flutter SDK — in-app feedback and survey collection for Flutter apps
Beta
This SDK is currently in beta. APIs may change, and we welcome your feedback. Use with caution in production environments.
Official Flutter SDK for Encatch — in-app feedback and survey collection.
Installation
Add encatch_flutter to your pubspec.yaml:
dependencies:
encatch_flutter: ^1.0.0Android Setup
Add internet permission to android/app/src/main/AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET" />iOS Setup
No additional setup required. The SDK uses flutter_inappwebview which works out of the box.
Quick Start
1. Wrap your app with EncatchProvider
import 'package:encatch_flutter/encatch_flutter.dart';
void main() {
runApp(
EncatchProvider(
apiKey: 'your-api-key',
child: MyApp(),
),
);
}2. Identify users
await Encatch.identifyUser(
'user@example.com',
traits: UserTraits(
set: {'name': 'Jane Doe', 'plan': 'pro'},
),
);3. Track events
await Encatch.trackEvent('button_clicked');4. Track screens
await Encatch.trackScreen('HomeScreen');Add EncatchNavigatorObserver for automatic screen tracking:
MaterialApp(
navigatorObservers: [EncatchNavigatorObserver()],
// ...
)5. Show a form manually
await Encatch.showForm('your-form-slug');6. Listen to form events
final unsubscribe = Encatch.on((eventType, payload) {
print('Event: $eventType, payload: ${payload.data}');
});
// Later, to stop listening:
unsubscribe();7. Pre-fill responses
Encatch.addToResponse('question_id', 'pre-filled value');
await Encatch.showForm('your-form-slug');Configuration
Configure the SDK via EncatchConfig when wrapping your app:
EncatchProvider(
apiKey: 'your-api-key',
config: EncatchConfig(
theme: EncatchTheme.system,
debugMode: true,
isFullScreen: false,
apiBaseUrl: 'https://app.encatch.com',
appVersion: '1.2.3',
onBeforeShowForm: (payload) async {
// Return false to prevent form from showing
return true;
},
),
child: MyApp(),
)Configuration Options
Prop
Type
API Reference
EncatchProvider
Top-level widget that initializes the Encatch SDK. Wrap your app's root widget to initialize the SDK with your API key, start a session automatically, and mount the headless WebView form listener.
EncatchProvider(
apiKey: 'your-api-key',
config: EncatchConfig(...), // optional
child: MyApp(),
)Prop
Type
Initialization
Initialize the SDK manually. Safe to call multiple times.
await Encatch.init('your-api-key');Prop
Type
User Identification
Identify the current user. The userName is required (can be a username, email, or unique identifier). Traits and options are optional.
await Encatch.identifyUser('user@example.com');await Encatch.identifyUser(
'user@example.com',
traits: UserTraits(
set: {'name': 'Alice', 'plan': 'pro'},
),
);await Encatch.identifyUser(
'user@example.com',
traits: UserTraits(
set: {'name': 'Alice', 'plan': 'pro'},
setOnce: {'firstSeen': DateTime.now()},
increment: {'loginCount': 1},
decrement: {'credits': 5},
unset: ['trialEndDate'],
),
);await Encatch.identifyUser(
'user@example.com',
options: IdentifyOptions(
secure: SecureOptions(
signature: 'your-hmac-signature',
generatedDateTimeinUTC: '2025-03-13T12:00:00Z',
),
),
);Prop
Type
User traits support the following operations:
| Operation | Description |
|---|---|
set | Set user attributes (overwrites existing values) |
setOnce | Set user attributes only if they don't already exist |
increment | Increment numeric user attributes |
decrement | Decrement numeric user attributes |
unset | Remove user attributes |
Secure Identification
Recommended
Using the secure option with a server-generated signature is recommended to verify that identification requests come from your backend. Keep your secret key on the server only — never expose it in client-side code.
Pass a server-generated HMAC signature so Encatch can validate the request. The generatedDateTimeinUTC timestamp limits the signature's lifespan.
await Encatch.identifyUser(
'user@example.com',
options: IdentifyOptions(
secure: SecureOptions(
signature: 'your-hmac-signature',
generatedDateTimeinUTC: '2025-03-13T12:00:00Z',
),
),
);Locale
Set the user's preferred language.
await Encatch.setLocale('fr');Country
Set the user's country.
await Encatch.setCountry('FR'); // ISO 3166 country codeTheme
Set the theme for forms and surveys.
Encatch.setTheme(EncatchTheme.dark);
Encatch.setTheme(EncatchTheme.light);
Encatch.setTheme(EncatchTheme.system); // Follows system preferenceEvent Tracking
Track a custom event.
await Encatch.trackEvent('button_clicked');
await Encatch.trackEvent('purchase_completed');Screen Tracking
Track screen navigation.
await Encatch.trackScreen('HomeScreen');
await Encatch.trackScreen('CheckoutScreen');EncatchNavigatorObserver
Add to MaterialApp.navigatorObservers for automatic screen tracking:
MaterialApp(
navigatorObservers: [EncatchNavigatorObserver()],
routes: {
'/': (context) => HomeScreen(),
'/settings': (context) => SettingsScreen(),
},
)Session
Manually start a new session. Called automatically by EncatchProvider.
await Encatch.startSession();Reset User
Reset the current user identity and clear all persisted data. Reverts the SDK to anonymous mode.
await Encatch.resetUser();Show Form
Show a specific form by slug or ID.
await Encatch.showForm('feedback-form');
await Encatch.showForm('feedback-form', options: ShowFormOptions(
reset: ResetMode.always,
));Prop
Type
Prop
Type
| ResetMode | Behavior |
|---|---|
ResetMode.always | Reset pre-fill and response data on every form display |
ResetMode.onComplete | Reset only after the form is completed |
ResetMode.never | Never reset response data |
Dismiss Form
Dismiss the currently displayed form.
await Encatch.dismissForm();
// Or dismiss a specific form configuration:
await Encatch.dismissForm(formConfigurationId: 'config-id');Prepopulate Response
Pre-fill a form response before showing a form.
Encatch.addToResponse('question_id', 'pre-filled value');
Encatch.addToResponse('choice_question_id', ['option-a', 'option-b']);
await Encatch.showForm('your-form-slug');Event Subscription
Subscribe to form lifecycle events. Returns an unsubscribe function.
final unsubscribe = Encatch.on((eventType, payload) {
print('Event: $eventType, payload: ${payload.data}');
});
// Later, to unsubscribe:
unsubscribe();| Event | Description |
|---|---|
EventType.formShow | Fired when a form is displayed |
EventType.formStarted | Fired when a user starts interacting |
EventType.formSubmit | Fired when a form is submitted |
EventType.formComplete | Fired when a form is fully completed |
EventType.formClose | Fired when a form is closed |
EventType.formDismissed | Fired when a form is dismissed without completion |
EventType.formError | Fired when an error occurs |
EventType.formSectionChange | Fired when the visible section changes |
EventType.formAnswered | Fired when a question is answered |
Form Interceptor
Use onBeforeShowForm in EncatchConfig to conditionally block forms from showing.
EncatchProvider(
apiKey: 'your-api-key',
config: EncatchConfig(
onBeforeShowForm: (payload) async {
// Inspect payload.formId, payload.formConfig, payload.triggerType, etc.
if (payload.triggerType == TriggerType.automatic && someCondition) {
return false; // Block this form
}
return true; // Allow
},
),
child: MyApp(),
)Custom Native Forms
Use buildSubmitRequest and Encatch.submitForm when building your own native form UI instead of the WebView overlay.
import 'package:encatch_flutter/encatch_flutter.dart';
final request = buildSubmitRequest(
options: BuildSubmitRequestOptions(
formConfigurationId: 'config-id',
triggerType: TriggerType.manual,
responseLanguageCode: 'en',
completionTimeInSeconds: 45,
isPartialSubmit: false,
feedbackIdentifier: 'optional-id',
),
responses: [
NativeFormResponse(questionId: 'q1', type: 'rating', value: 5),
NativeFormResponse(questionId: 'q2', type: 'nps', value: 9),
NativeFormResponse(questionId: 'q3', type: 'short_answer', value: 'Great!'),
NativeFormResponse(questionId: 'q4', type: 'long_text', value: 'Detailed feedback...'),
NativeFormResponse(questionId: 'q5', type: 'single_choice', value: 'option-a'),
NativeFormResponse(questionId: 'q6', type: 'multiple_choice', value: ['a', 'b']),
],
);
await Encatch.submitForm(request);| Type | Value type | Description |
|---|---|---|
rating | int | Numeric rating |
nps | int | NPS score |
short_answer | String | Short text response |
long_text | String | Long text response |
single_choice | String | Single option selected |
multiple_choice | List<String> | Multiple options selected |
Requirements
- Dart SDK:
>=3.11.0 <4.0.0 - Flutter:
>=3.41.0
Dependencies
The SDK uses:
flutter_inappwebview— WebView for form displayshared_preferences— Persistencedevice_info_plus— Device metadatapackage_info_plus— App versionuuid— ID generationhttp— API requests
Raising Issues
GitHub Repository: github.com/get-encatch/flutter-sdk

