When converting Markdown to Lexical, standard image syntax ![alt] (url) is not automatically converted to Upload nodes, because Payload has no way to look up a Media document from a URL alone.
The UploadFeature includes a built-in transformer that recognizes a special placeholder format:
1
![media:6507f7b9a4d3c2e1f0ab1234]()
Where media is your upload collection slug and the second part is the document ID. When convertMarkdownToLexical processes this, it creates a proper Upload node with the correct relationTo and value.
When converting from Lexical to Markdown, Upload nodes are serialized back into this same placeholder format (unless the document is populated, in which case the URL and alt text are used directly as a standard markdown image).
Payload supports serializing and deserializing MDX content. While Markdown converters are stored on the features, MDX converters are stored on the blocks that you pass to the BlocksFeature.
content:markdownToLexical({ markdown: children }),
53
}
54
},
55
},
56
}
57
58
constPages:CollectionConfig={
59
slug:'pages',
60
fields:[
61
{
62
name:'nameOfYourRichTextField',
63
type:'richText',
64
editor:lexicalEditor({
65
features:({ defaultFeatures })=>[
66
...defaultFeatures,
67
BlocksFeature({
68
blocks:[BannerBlock],
69
}),
70
],
71
}),
72
},
73
{
74
name:'markdown',
75
type:'textarea',
76
hooks:{
77
afterRead:[
78
({ siblingData, siblingFields })=>{
79
const data:SerializedEditorState=
80
siblingData['nameOfYourRichTextField']
81
82
if(!data){
83
return''
84
}
85
86
const markdown =convertLexicalToMarkdown({
87
data,
88
editorConfig: editorConfigFactory.fromField({
89
field: siblingFields.find(
90
(field)=>
91
'name'in field && field.name==='nameOfYourRichTextField',
92
)asRichTextField,
93
}),
94
})
95
96
return markdown
97
},
98
],
99
beforeChange:[
100
({ siblingData })=>{
101
// Ensure that the markdown field is not saved in the database
102
delete siblingData['markdown']
103
returnnull
104
},
105
],
106
},
107
},
108
],
109
}
The conversion is done using the jsx property of the block. The export function is called when converting from lexical to MDX, and the import function is called when converting from MDX to lexical.