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:
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:
The lexicalHTMLField() helper converts JSON to HTML and saves it in a field that is updated every time you read it via an afterRead hook. It's generally not recommended for two reasons:
It creates a column with duplicate content in another format.