Skip to main content

Overview

The HTML Encoder converts AppFlowy Editor Document objects into HTML strings. It provides a parser-based system that transforms document nodes into semantic HTML elements.

DocumentHTMLEncoder

The main class for encoding documents to HTML format.

Constructor

DocumentHTMLEncoder({
  List<HTMLNodeParser> encodeParsers = const [],
})

Parameters

  • encodeParsers (List<HTMLNodeParser>): List of node parsers that define how each node type is converted to HTML. Default is an empty list.

Methods

convert

String convert(Document input)
Converts a complete Document to an HTML string. Parameters:
  • input (Document): The document to convert
Returns: String - The HTML representation of the document Example:
final encoder = DocumentHTMLEncoder(
  encodeParsers: [
    const HTMLTextNodeParser(),
    const HTMLBulletedListNodeParser(),
    const HTMLNumberedListNodeParser(),
    const HTMLTodoListNodeParser(),
    const HTMLQuoteNodeParser(),
    const HTMLHeadingNodeParser(),
    const HTMLImageNodeParser(),
    const HtmlTableNodeParser(),
    const HTMLDividerNodeParser(),
  ],
);

final html = encoder.convert(document);

Helper Function

documentToHTML

A convenient helper function that provides a simpler API with default parsers.
String documentToHTML(
  Document document, {
  List<HTMLNodeParser> customParsers = const [],
})
Parameters:
  • document (Document): The document to convert
  • customParsers (List<HTMLNodeParser>): Additional custom parsers to use
Returns: String - The HTML string Example:
import 'package:appflowy_editor/appflowy_editor.dart';

// Simple usage with default parsers
final html = documentToHTML(document);

// With custom parsers
final html = documentToHTML(
  document,
  customParsers: [MyCustomHTMLParser()],
);

Supported Node Types

The encoder converts document nodes to the following HTML elements:

Text and Formatting

  • Paragraphs: <p> tags
  • Bold: <strong> tags or <span style="font-weight: bold">
  • Italic: <i> or <em> tags or <span style="font-style: italic">
  • Underline: <u> tags or <span style="text-decoration: underline">
  • Strikethrough: <del> or <s> tags or <span style="text-decoration: line-through">
  • Code: <code> tags
  • Links: <a href="..."> tags

Block Elements

  • Headings: <h1> through <h6> tags
  • Bulleted Lists: <ul> with <li> items
  • Numbered Lists: <ol> with <li> items
  • Todo Lists: <ul> with <li> containing checkbox indicators
  • Block Quotes: <blockquote> tags
  • Images: <img> tags with src and align attributes
  • Tables: <table> with proper structure
  • Dividers: <hr> tags
  • Line Breaks: <br> tags

Example Output

final document = Document.fromJson({
  'type': 'page',
  'children': [
    {
      'type': 'heading',
      'data': {
        'level': 1,
        'delta': [{'insert': 'AppFlowy Editor'}]
      }
    },
    {
      'type': 'heading',
      'data': {
        'level': 2,
        'delta': [
          {'insert': '👋 '},
          {'insert': 'Welcome to', 'attributes': {'bold': true}},
          {'insert': ' AppFlowy Editor', 'attributes': {'bold': true, 'italic': true}}
        ]
      }
    },
    {
      'type': 'paragraph',
      'data': {
        'delta': [
          {'insert': 'A '},
          {'insert': 'customizable', 'attributes': {'bold': true}},
          {'insert': ' editor'}
        ]
      }
    },
    {
      'type': 'bulleted_list',
      'data': {
        'delta': [{'insert': 'First item'}]
      }
    },
    {
      'type': 'quote',
      'data': {
        'delta': [{'insert': 'This is a quote!'}]
      }
    },
    {'type': 'divider'}
  ]
});

final html = documentToHTML(document);
// Output:
// <h1>AppFlowy Editor</h1>
// <h2>👋 <strong>Welcome to</strong> <span style="font-weight: bold; font-style: italic">AppFlowy Editor</span></h2>
// <p>A <strong>customizable</strong> editor</p>
// <ul><li>First item</li></ul>
// <blockquote>This is a quote!</blockquote>
// <hr>

Inline Styles

The encoder generates inline styles for certain attributes:
final delta = [
  {
    'insert': 'Styled text',
    'attributes': {
      'bold': true,
      'italic': true,
      'underline': true,
      'strikethrough': true,
    }
  }
];

// Generates:
// <span style="font-weight: bold; font-style: italic; text-decoration: underline line-through">Styled text</span>

Nested Content

The encoder properly handles nested structures:
final document = Document.fromJson({
  'type': 'page',
  'children': [
    {
      'type': 'bulleted_list',
      'children': [
        {
          'type': 'image',
          'data': {
            'url': 'https://example.com/image.png',
            'align': 'center'
          }
        }
      ],
      'data': {'delta': []}
    }
  ]
});

final html = documentToHTML(document);
// Generates nested structure with image inside list item

Custom Parsers

Create custom HTML parsers by implementing the HTMLNodeParser interface:
class CustomHTMLParser extends HTMLNodeParser {
  const CustomHTMLParser();

  @override
  String get id => 'custom_node_type';

  @override
  String transformNodeToHTMLString(
    Node node, {
    required List<HTMLNodeParser> encodeParsers,
  }) {
    // Custom transformation logic
    final content = node.attributes['content'];
    return '<div class="custom">$content</div>';
  }
}

// Use your custom parser
final html = documentToHTML(
  document,
  customParsers: [const CustomHTMLParser()],
);

Table Support

The encoder generates proper HTML table structure:
final tableDocument = Document.fromJson({
  'type': 'page',
  'children': [
    {
      'type': 'table',
      'data': {
        'colsLen': 2,
        'rowsLen': 2,
      },
      'children': [
        {
          'type': 'table/cell',
          'data': {'colPosition': 0, 'rowPosition': 0},
          'children': [
            {'type': 'paragraph', 'data': {'delta': [{'insert': 'A'}]}}
          ]
        },
        {
          'type': 'table/cell',
          'data': {'colPosition': 1, 'rowPosition': 0},
          'children': [
            {'type': 'paragraph', 'data': {'delta': [{'insert': 'B'}]}}
          ]
        }
      ]
    }
  ]
});

final html = documentToHTML(tableDocument);
// Generates proper <table> structure with <tr> and <td> elements

Empty Paragraphs

Empty paragraphs are converted to <br> tags:
final document = Document.fromJson({
  'type': 'page',
  'children': [
    {'type': 'paragraph', 'data': {'delta': []}},
    {'type': 'paragraph', 'data': {'delta': []}}
  ]
});

final html = documentToHTML(document);
// Output: <br><br>

See Also

Build docs developers (and LLMs) love