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.
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, as it creates a column with duplicate content in another format.