Import and export

An import button and an export menu. Export downloads a file in the browser.

Installation

This pattern is built from files in @intentui/editor. Install the editor, then copy the code above into a component of your own.

npx shadcn@latest add @intentui/editor

What's included

PieceWhy it is here
RichTextExtensionLexical's rich text behavior. Every pattern needs it.
InitialStateExtensionApplies the seeded content immediately, so the server and the client render the same. Leave it out if your editor starts empty. See Seeding initial content.
ListExtension, CheckListExtensionRegister list nodes, so lists survive import and appear in Markdown.
LinkExtensionRegisters link nodes.
CodeExtensionRegisters code block nodes.
TableExtensionRegisters table nodes.
HorizontalRuleExtensionRegisters the divider node.
ImageExtensionRegisters the image node.
EmojiExtensionRegisters the emoji node.
EDITOR_TRANSFORMERSThe Markdown transformer list passed to the plugin. See below.
ImportExportToolbarPluginThe import button and export menu.
ToolbarThe container that holds toolbar plugins. See Toolbar.

A file can only be imported if the editor registers every node type in it. If you remove an extension above, files containing that block fail to import.

Formats

ControlResult
Import fileOpens a file picker and loads a Lexical file into the editor.
Export as, Lexical JSONDownloads a Lexical file that Import can read back.
Export as, MarkdownDownloads a .md file.
Export as, HTMLDownloads an .html file with the content inside body.

Import reads Lexical files only. It does not read Markdown or HTML. File names are the editor namespace plus the current ISO timestamp, with unsafe characters replaced. See the file and markdown docs for the formats.

Markdown transformers

Markdown export uses a list of transformers. If you pass none, the plugin falls back to Lexical's stock TRANSFORMERS, which do not know about tables, dividers, images or emoji, so those blocks do not round-trip. editor.tsx defines a fuller list and passes it, and this pattern does the same:

const EDITOR_TRANSFORMERS: Transformer[] = [
  TABLE,
  HR,
  IMAGE,
  EMOJI,
  CHECK_LIST,
  ...ELEMENT_TRANSFORMERS,
  ...MULTILINE_ELEMENT_TRANSFORMERS,
  ...TEXT_FORMAT_TRANSFORMERS,
  ...TEXT_MATCH_TRANSFORMERS,
];

<ImportExportToolbarPlugin transformers={EDITOR_TRANSFORMERS} />

If you add a block that should appear in Markdown, add its transformer to the list. The full editor passes the same list to registerMarkdownShortcuts, so the same transformers also power Markdown shortcuts while typing. This pattern does not register those.

API

Props of ImportExportToolbarPlugin.
transformersTransformer[]
Transformers used for Markdown export. Defaults to TRANSFORMERS from @lexical/markdown.
Default: TRANSFORMERS