eddyter_flutter

pub version

The official Flutter widget for the Eddyter rich text editor.

The editor is a web editor (Lexical). This package does not reimplement it natively: it loads the published @eddyter/core build inside a WebView and bridges events and file exports to Flutter. Android and iOS are supported.

Eddyter Editor

Resources

Requirements

  • Flutter 3.44+ (Dart 3.12+)
  • Android 5.0+ (API 21) / iOS 13+
  • An Eddyter license key

Installation

flutter pub add eddyter_flutter

or add it to your app's pubspec.yaml:

dependencies:
  eddyter_flutter: ^1.0.2

Then run flutter pub get. On iOS, run cd ios && pod install if your build doesn't do it for you.

Quick Start

1. Get your API key

  1. Create an account at eddyter.com
  2. Navigate to License Keys in your dashboard
  3. Copy your API key

The license key is bound to your app's Android applicationId / iOS bundle id. The widget reads that id from the compiled app with package_info_plus and sends it as X-Eddyter-App-Id; you cannot set or override it.

On the first successful validation the key is locked to app://<id>. A second app with a different id gets LICENSE_IN_USE until you Unassign the key on the License Keys page. Debug and release builds of the same id share one binding.

2. Configure Android

The plugin already declares the camera and legacy storage permissions it needs. Add the rest to android/app/src/main/AndroidManifest.xml:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>

And a package-visibility query (inside <manifest>) so the share sheet can open after an export:

<queries>
  <intent>
    <action android:name="android.intent.action.SEND"/>
    <data android:mimeType="*/*"/>
  </intent>
</queries>
  • Speech-to-text needs RECORD_AUDIO and MODIFY_AUDIO_SETTINGS. The widget asks for the runtime permission itself.
  • Image upload uses the camera or the system photo picker.
  • Export to Downloads: Android 10+ saves through MediaStore and needs no permission. Android 9 and below use WRITE_EXTERNAL_STORAGE (declared by the plugin) and prompt once.

3. Configure iOS

Add these keys to ios/Runner/Info.plist. Missing camera / photo keys crash the app when the editor opens Take Photo:

<key>NSMicrophoneUsageDescription</key>
<string>The editor uses the microphone for speech-to-text.</string>
<key>NSCameraUsageDescription</key>
<string>The editor uses the camera to take photos for image upload.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>The editor uses the photo library to attach images.</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>The editor may save photos you capture for image upload.</string>

The widget requests microphone access itself. If you also use permission_handler elsewhere in your app, add PERMISSION_MICROPHONE=1 and PERMISSION_CAMERA=1 to your Podfile GCC_PREPROCESSOR_DEFINITIONS (see that package's README).

4. Add the widget

import 'package:eddyter_flutter/eddyter_flutter.dart';

class NoteEditorScreen extends StatefulWidget {
  const NoteEditorScreen({super.key});

  @override
  State<NoteEditorScreen> createState() => _NoteEditorScreenState();
}

class _NoteEditorScreenState extends State<NoteEditorScreen> {
  String _html = '<p>Hello from Flutter</p>';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Note')),
      body: Eddyter(
        apiKey: 'YOUR_API_KEY',
        initialContent: _html,
        showStatus: false,
        onChange: (html) => _html = html,
        onReady: () => debugPrint('Editor ready'),
        onError: (error) => debugPrint('Eddyter: $error'),
        onExportSuccess: (path) => debugPrint('Saved $path'),
      ),
    );
  }
}

Give the widget a bounded height, for example as a Scaffold body or wrapped in Expanded inside a Column.

Keep the API key out of source control, for example with --dart-define=API_KEY=... and const String.fromEnvironment('API_KEY').

API Reference

Eddyter

Parameter Type Notes
apiKey String Required. Your Eddyter license key.
initialContent String HTML the editor starts with. Default <p>Start writing...</p>.
showStatus bool Shows a loading / error strip at the bottom until the editor is ready. Default true.
exportMode EddyterExportMode? share, save or both. Default: Android both, iOS share.
exportFilePrefix String? Prefix for exported file names.
sdkVersion String @eddyter/core version loaded from unpkg. Defaults to kDefaultEddyterSdkVersion, the version this release is tested with.
sdkScriptUrl / sdkStyleUrl String? Load the editor JS / CSS from your own host instead of unpkg.

Callbacks

Parameter Signature
onChange void Function(String html)
onReady void Function()
onAuthSuccess void Function()
onAuthError void Function(String error)
onExportSuccess void Function(String filePath). A content:// URI or Downloads path when saved on Android.
onExportError void Function(String error). onError is also called.
onError void Function(String error). Load, network, license and runtime errors.

Exporting PDF and Word

Browser downloads (<a download>) don't work inside a WebView. The widget catches PDF / DOCX exports from the toolbar, writes the file to the app's documents directory, saves it to the public Downloads folder on Android (MediaStore or DownloadManager), and opens the system share sheet. Use exportMode to change this.

Notes

  • The device needs network access: the editor loads from unpkg on startup, and the license key is validated online.

  • Some Huawei devices render a blank WebView with Impeller. If you see this, disable Impeller inside <application> in your app's AndroidManifest.xml:

    <meta-data
        android:name="io.flutter.embedding.android.EnableImpeller"
        android:value="false" />
    

License

Eddyter is proprietary software.

  • Free for evaluation and non-commercial use
  • Commercial use requires a paid license
  • SaaS, redistribution, and competing products are prohibited without permission

For commercial licensing, visit eddyter.com.

Libraries

eddyter_flutter