There are two main approaches to convert your Lexical-based rich text to HTML:
Generate HTML on-demand (Recommended): Convert JSON to HTML wherever you need it, on-demand.
Generate HTML within your Collection: Create a new field that automatically converts your saved JSON content to HTML. This is not recommended because it adds overhead to the Payload API and may not work well with live preview.
To convert JSON to HTML on-demand, use the convertLexicalToHTML function from @payloadcms/richtext-lexical/html. Here's an example of how to use it in a React component in your frontend:
To automatically generate HTML from the saved richText field in your Collection, use the lexicalHTMLField() helper. This approach converts the JSON to HTML using an afterRead hook. For instance:
By default, convertLexicalToHTML expects fully populated data (e.g. uploads, links, etc.). If you need to dynamically fetch and populate those nodes, use the async variant, convertLexicalToHTMLAsync, from @payloadcms/richtext-lexical/html-async. You must provide a populate function:
exportconstMyComponent=({ data }:{ data:SerializedEditorState})=>{
10
const[html, setHTML]=useState<null|string>(null)
11
useEffect(()=>{
12
asyncfunctionconvert(){
13
const html =awaitconvertLexicalToHTMLAsync({
14
data,
15
populate:getRestPopulateFn({
16
apiURL:`http://localhost:3000/api`,
17
}),
18
})
19
setHTML(html)
20
}
21
22
voidconvert()
23
},[data])
24
25
return html &&<divdangerouslySetInnerHTML={{ __html: html }}/>
26
}
Using the REST populate function will send a separate request for each node. If you need to populate a large number of nodes, this may be slow. For improved performance on the server, you can use the getPayloadPopulateFn function: