feat(richtext-lexical): add markdown transformer for upload nodes#15630
Merged
GermanJablo merged 3 commits intopayloadcms:mainfrom Feb 19, 2026
Merged
Conversation
Upload nodes were silently dropped when converting Lexical content to markdown. This adds an ElementTransformer that outputs upload nodes as standard markdown image syntax when the value is populated:  For non-image uploads, it outputs a link instead: [document.pdf](/uploads/document.pdf) When the upload value is not populated (just an ID), a reference placeholder is output so the data is not silently lost: ![collection:id]() Fixes payloadcms#13086
GermanJablo
approved these changes
Feb 19, 2026
Contributor
There was a problem hiding this comment.
Test plan
- Verified that upload nodes with populated data (containing
url,alt,filename) produce valid markdown image syntax- Verified that non-image uploads produce link syntax
- Verified that non-populated uploads produce a reference placeholder instead of being dropped
Thank you. For next time, if possible, it would be very helpful to include the tests.
As a separate note, we've discussed internally with @AlessioGr how we can further improve the Markdown conversion experience in the future. Ideas to explore:
- Intelligent URL recognition (including Link Nodes, if possible).
- Do the same for internal links in LinkNode
- A new parameter in
convertLexicalToMarkdownthat allows adding or customizing transformers.
Contributor
|
🚀 This is included in version v3.78.0 |
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When converting Lexical rich text content to markdown using
convertLexicalToMarkdown, upload nodes (images and files) are completely stripped from the output. There's no markdown transformer registered for the upload feature, so the converter silently drops them.This means any content that includes uploaded images loses those images entirely when exported to markdown - which is unexpected since other node types like links, headings, and horizontal rules all have proper markdown transformers.
Fix
Added an
ElementTransformerfor upload nodes that handles three cases:Populated image uploads - outputs standard markdown image syntax:
Populated non-image uploads (PDFs, docs, etc.) - outputs a link:
Non-populated uploads (value is just an ID) - outputs a reference placeholder so the data isn't silently lost:
The transformer is registered in the
UploadFeatureserver configuration alongside the existing HTML converter.The import side (markdown -> Lexical) uses a never-matching regex because upload nodes should be created through the upload UI/drawer, not parsed from markdown text.
Test plan
url,alt,filename) produce valid markdown image syntaxFixes #13086