Skip to main content
AppFlowy Editor includes built-in support for internationalization (i18n) and localization (l10n), with 23 languages supported out of the box.

Supported Languages

AppFlowy Editor currently supports the following locales:
  • English (en)
  • Bengali (bn_BN)
  • Catalan (ca)
  • Czech (cs_CZ)
  • Danish (da)
  • German (de_DE)
  • Spanish (es_VE)
  • French (fr_FR, fr_CA)
  • Hindi (hi_IN)
  • Hungarian (hu_HU)
  • Indonesian (id_ID)
  • Italian (it_IT)
  • Japanese (ja_JP)
  • Malayalam (ml_IN)
  • Dutch (nl_NL)
  • Polish (pl_PL)
  • Portuguese (pt_BR, pt_PT)
  • Russian (ru_RU)
  • Turkish (tr_TR)
  • Chinese (zh_CN, zh_TW)

Basic Setup

To enable localization in your Flutter app, add the localization delegates:
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // Add localization delegates
      localizationsDelegates: [
        GlobalMaterialLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        AppFlowyEditorLocalizations.delegate,
      ],
      // Specify supported locales
      supportedLocales: AppFlowyEditorLocalizations.delegate.supportedLocales,
      // Your app configuration
      home: EditorPage(),
    );
  }
}

Setting a Specific Locale

You can set a specific locale for your app:
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:flutter/material.dart';

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      localizationsDelegates: [
        AppFlowyEditorLocalizations.delegate,
        // Other delegates...
      ],
      // Set French as the locale
      locale: const Locale('fr', 'FR'),
      supportedLocales: AppFlowyEditorLocalizations.delegate.supportedLocales,
      home: EditorPage(),
    );
  }
}

Dynamic Locale Switching

You can change the locale at runtime:
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';

class LocaleSwitcher extends StatefulWidget {
  @override
  State<LocaleSwitcher> createState() => _LocaleSwitcherState();
}

class _LocaleSwitcherState extends State<LocaleSwitcher> {
  void toggleLocale() {
    final currentLocale = Intl.getCurrentLocale();
    
    if (currentLocale.startsWith('en')) {
      // Switch to Portuguese
      AppFlowyEditorLocalizations.load(const Locale('pt', 'BR'));
    } else {
      // Switch back to English
      AppFlowyEditorLocalizations.load(const Locale('en', 'US'));
    }
    
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return FloatingActionButton(
      onPressed: toggleLocale,
      child: const Icon(Icons.language),
    );
  }
}

Accessing Localized Strings

You can access localized strings using the AppFlowyEditorLocalizations class:
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:flutter/material.dart';

class LocalizedWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final l10n = AppFlowyEditorLocalizations.of(context);
    
    return Column(
      children: [
        Text(l10n.bold), // Displays "Bold" in current locale
        Text(l10n.italic), // Displays "Italic" in current locale
        Text(l10n.underline), // Displays "Underline" in current locale
      ],
    );
  }
}

Available Localized Strings

Text Formatting

final l10n = AppFlowyEditorLocalizations.of(context);

l10n.bold          // "Bold"
l10n.italic        // "Italic"
l10n.underline     // "Underline"
l10n.strikethrough // "Strikethrough"
l10n.code          // "Code"
l10n.highlight     // "Highlight"

Block Types

l10n.heading1      // "H1"
l10n.heading2      // "H2"
l10n.heading3      // "H3"
l10n.text          // "Text"
l10n.bulletedList  // "Bulleted List"
l10n.numberedList  // "Numbered List"
l10n.checkbox      // "Checkbox"
l10n.quote         // "Quote"
l10n.divider       // "Divider"
l10n.table         // "Table"

Colors

l10n.color                  // "Color"
l10n.backgroundColor        // "Background Color"
l10n.highlightColor        // "Highlight Color"
l10n.fontColorDefault      // "Default"
l10n.fontColorRed          // "Red"
l10n.fontColorBlue         // "Blue"
// ... and more color options

Actions

l10n.done                  // "Done"
l10n.cancel                // "Cancel"
l10n.copy                  // "Copy"
l10n.paste                 // "Paste"
l10n.cut                   // "Cut"
l10n.find                  // "Find"
l10n.replace               // "Replace"
l10n.replaceAll            // "Replace all"
l10n.link                  // "Link"
l10n.addYourLink          // "Add your link"
l10n.openLink             // "Open link"
l10n.copyLink             // "Copy link"
l10n.removeLink           // "Remove link"
l10n.editLink             // "Edit link"

Adding a New Language

To contribute a new language translation:

1. Install Flutter Intl Plugin

Install the Flutter Intl VSCode extension.

2. Create Translation File

Create a new .arb file in lib/l10n/ directory:
cd appflowy-editor/lib/l10n
cp intl_en.arb intl_<locale>.arb
For example, to add Korean:
cp intl_en.arb intl_ko_KR.arb

3. Translate Strings

Edit the new .arb file and translate all strings:
{
  "@@locale": "ko_KR",
  "bold": "굵게",
  "italic": "기울임",
  "underline": "밑줄",
  "strikethrough": "취소선",
  // ... translate all other strings
}

4. Generate Localization Code

Save the file, and the Flutter Intl plugin will automatically generate the necessary Dart code.

5. Verify the Translation

Test your translation by setting the locale:
supportedLocales: const [Locale('ko', 'KR')],

Modifying Existing Translations

  1. Locate the translation file in lib/l10n/intl_<locale>.arb
  2. Modify the desired strings
  3. Save the file (code will auto-generate)
  4. Rebuild your app to see changes

Testing Translations

You can test translations interactively:
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:flutter/material.dart';

class TranslationTester extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Translation Test')),
      body: ListView(
        children: [
          // Test each locale
          ListTile(
            title: Text('English'),
            onTap: () {
              AppFlowyEditorLocalizations.load(const Locale('en'));
            },
          ),
          ListTile(
            title: Text('日本語'),
            onTap: () {
              AppFlowyEditorLocalizations.load(const Locale('ja', 'JP'));
            },
          ),
          ListTile(
            title: Text('中文'),
            onTap: () {
              AppFlowyEditorLocalizations.load(const Locale('zh', 'CN'));
            },
          ),
        ],
      ),
    );
  }
}

RTL (Right-to-Left) Support

AppFlowy Editor supports RTL languages:
import 'package:appflowy_editor/appflowy_editor.dart';

final l10n = AppFlowyEditorLocalizations.of(context);

l10n.ltr  // "LTR"
l10n.rtl  // "RTL"
l10n.auto // "Auto"
The editor automatically adjusts text direction based on content.

Best Practices

  1. Always use localized strings: Never hardcode UI strings
  2. Test with long strings: Some languages (German, French) have longer text
  3. Support text direction: Ensure your layout works with RTL languages
  4. Context matters: Some words translate differently based on context
  5. Date and number formatting: Use intl package for proper formatting

Contributing Translations

To contribute translations to AppFlowy Editor:
  1. Fork the repository
  2. Add or modify translation files in lib/l10n/
  3. Test your changes
  4. Submit a pull request
See the Translation Guide for detailed instructions.

Build docs developers (and LLMs) love