Pingolin
Pingolin

Reputation: 3417

Convert Lexical to HTML

I am trying to export the content of my RTE developed with Lexical in HTML format. To do so, I have a button with an handleClick function which is supposed to console.log the content of the RTE in HTML.

When I try to export the content as a stringified JSON, there is no problem, I can see my content, for example:

{"root":{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"test content","type":"text","version":1}],"direction":"ltr","format":"","indent":0,"type":"paragraph","version":1}],"direction":"ltr","format":"","indent":0,"type":"root","version":1}}

However as soon as I try to convert the content to HTML, I keep having an empty string.

Any idea what I could be doing wrong here? Here is the function supposed to export the content to HTML:

import { $generateHtmlFromNodes } from '@lexical/html';

const handleClick = (editor: LexicalEditor) => {
  editor.update(() => {
    const editorState = editor.getEditorState();
    const jsonString = JSON.stringify(editorState);
    console.log('jsonString', jsonString);

    const htmlString = $generateHtmlFromNodes(editor);
    console.log('htmlString', htmlString);
  });
};

Thank you

Upvotes: 8

Views: 11691

Answers (3)

Leffa
Leffa

Reputation: 494

If you is using Next.js, I create a hook to show JSON to HTML.

'use client'

  import { useEffect, useState } from 'react'
  import { $generateHtmlFromNodes } from '@lexical/html' 
  import { createEditor } from 'lexical'

  export function useLexicalToHtml(lexicalJson: string) {
  const [htmlContent, setHtmlContent] = useState('')

  useEffect(() => {
    if (lexicalJson) {
      const editor = createEditor()
 
      try {
        editor.setEditorState(editor.parseEditorState(lexicalJson))

        editor.update(() => {
          const html = $generateHtmlFromNodes(editor)
          setHtmlContent(html)
        })
      } catch (err) {
           console.error('Error to convert JSON Lexical to HTML:', err)
      }
    }
  }, [lexicalJson])

  return htmlContent
}

Upvotes: 0

Jalal
Jalal

Reputation: 3644

Use a listener to get the latest update from the editor.

  React.useEffect(() => {
    const removeUpdateListener = editor.registerUpdateListener(
      ({ editorState }) => {
        editorState.read(() => {
          const htmlString = $generateHtmlFromNodes(editor, null);

          // Do something.
        });
      }
    );
    return () => {
      removeUpdateListener();
    };
  }, [editor]);

Upvotes: 3

Pingolin
Pingolin

Reputation: 3417

Finally found out what was the problem, the problem was that the function $generateHtmlFromNodes(editor, null) needs a second parameter as null, so the working solution is:

import { $generateHtmlFromNodes } from '@lexical/html';

const handleClick = (editor: LexicalEditor) => {
  editor.update(() => {
    const editorState = editor.getEditorState();
    const jsonString = JSON.stringify(editorState);
    console.log('jsonString', jsonString);

    const htmlString = $generateHtmlFromNodes(editor, null);
    console.log('htmlString', htmlString);
  });
};

Upvotes: 7

Related Questions