Skip to content

feat: Add Markdown Paste/Import to Rich Text Editor #2

@codewizdave

Description

@codewizdave

Overview

Add the ability to paste Markdown content directly into the Payload rich text editor (Lexical) and have it automatically convert to rich text format. This will make it much easier to create blog posts from existing Markdown files or documentation.

Status

Open - Ready to implement

Priority

Medium

Problem Statement

Currently, when creating or editing blog posts in Payload CMS:

  • Pasting Markdown results in plain text, not formatted content
  • Must manually format all content (headings, bold, lists, code blocks, etc.)
  • Time-consuming to convert existing Markdown articles to rich text
  • No easy way to import Markdown documentation or existing blog posts

Proposed Solution

Approach 1: Paste Handler (Recommended)

Add a paste handler to the Lexical editor that detects Markdown content and converts it automatically.

Benefits:

  • Seamless user experience - just paste and it works
  • No additional UI needed
  • Works with clipboard history
  • Most intuitive for users

Approach 2: Import Markdown Button

Add a button in the rich text editor toolbar that opens a modal for pasting/importing Markdown.

Benefits:

  • More explicit - user knows what's happening
  • Can include preview of converted content
  • Can import from file upload
  • Better for large Markdown documents

Approach 3: Hybrid (Best UX)

Combine both approaches:

  • Automatic paste detection for quick pastes
  • Import button for large content or file uploads
  • Toggle in settings to disable auto-convert if desired

Requirements

Functional Requirements

  1. Detect Markdown paste in rich text editor
  2. Convert Markdown to Lexical rich text format
  3. Support all common Markdown syntax:
    • Headings (# ## ### #### ##### ######)
    • Bold (text)
    • Italic (text)
    • Links text
    • Images alt
    • Code blocks (language ... )
    • Inline code (code)
    • Lists (unordered - and ordered 1.)
    • Blockquotes (> text)
    • Horizontal rules (--- or ***)
    • Tables (if possible)
  4. Preserve code block language for syntax highlighting
  5. Handle nested lists correctly
  6. Maintain proper spacing and line breaks

Non-Functional Requirements

  • Fast conversion (no lag when pasting)
  • Accurate conversion (matches expected formatting)
  • No data loss during conversion
  • Works with large Markdown files (up to 10,000 words)
  • Undo/redo support after paste
  • Error handling for invalid Markdown

Payload Lexical Built-in Support

Payload CMS provides built-in conversion functions:

import { convertMarkdownToLexical } from '@payloadcms/richtext-lexical'

const lexicalJSON = convertMarkdownToLexical({
  editorConfig: editorConfig,
  markdown: '# Hello world\n\nThis is a **test**.',
})

This means we don't need to write a custom Markdown parser!

Implementation Plan

Phase 1: Paste Handler (1 day)

  • Create custom Lexical feature for paste handling
  • Implement Markdown detection heuristics
  • Integrate convertMarkdownToLexical from Payload
  • Add to Posts collection rich text editor
  • Test with common Markdown patterns

Phase 2: Import Button (1 day)

  • Create custom toolbar button
  • Build modal component with Markdown textarea
  • Add preview pane (side-by-side)
  • Implement file upload (.md files)
  • Add insert/cancel actions

Phase 3: Enhanced Features (Optional)

  • Support for frontmatter (YAML)
  • Support for MDX syntax
  • Handle GitHub-flavored Markdown
  • Paste from URL (fetch remote Markdown)
  • Bulk import from folder

Testing Checklist

  • Paste simple Markdown (headings, paragraphs)
  • Paste Markdown with bold/italic
  • Paste Markdown with links
  • Paste Markdown with code blocks (with language)
  • Paste Markdown with lists (ordered/unordered)
  • Paste Markdown with blockquotes
  • Paste large Markdown files (1000+ words)
  • Paste regular text (should NOT convert)
  • Import button opens modal
  • File upload works for .md files
  • Preview shows correct conversion
  • Undo works after paste/import
  • No console errors
  • Works on all browsers (Chrome, Firefox, Safari)

Dependencies

  • @payloadcms/richtext-lexical (already installed)
  • Payload Lexical editor (already configured)
  • No additional packages needed

Related Issues

Refer to docs/issues/markdown-paste-import.md for full details.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions