Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't call blocksToHTMLLossy on document with React custom blocks without instantiating a BlockNoteView #720

Open
1 task
blx opened this issue May 3, 2024 · 0 comments
Labels
bug Something isn't working

Comments

@blx
Copy link

blx commented May 3, 2024

Describe the bug
<what's going wrong!?>

I want to render a document of blocks to HTML, "headlessly" ie. without showing the editor. But when some of my custom blocks are React-rendered (defined via createReactBlockSpec), an error is thrown when exporting to HTML without having instantiated a BlockNoteView.

blocksToHTMLLossy(), somewhere down the stack, depends on contentComponent being set on the inner editor._tiptapEditor (here), which is done by a useEffect in EditorContent that mutates the editor passed in , and EditorContent doesn't come into play without having a BlockNoteView.

I think this specific state of affairs was introduced in #641, but I haven't checked whether this would have worked before that.

For now, I'm just rendering a BlockNoteView on a throwaway React root, in order to get the mutation from EditorContent applied, which is fine, but a bit clunky.

I appreciate this is probably not a common use case 🙃

To Reproduce

const toHTML = async (blocks, schema=null) => BlockNoteEditor.create({
  initialContent: blocks,
  ...(schema ? { schema } : {})
}).blocksToHTMLLossy();

// Default schema block works fine:
console.log(await toHTML([{ type: 'paragraph', content: 'heya' }]));

// React-based custom element doesn't work...
const somethingBlock = createReactBlockSpec(
  { type: 'something', content: 'none', propSchema: {} },
  { render() { return <i>A constant something</i> } }
)
const customSchema = BlockNoteSchema.create({ blockSpecs: { something: somethingBlock } })

// ...Throws error:
console.log(await toHTML([{type: 'something'}], customSchema))

// But this works:
const editor = BlockNoteEditor.create({ initialContent: [{type: 'something'}], schema: customSchema });
await new Promise((resolve, reject) => {
  const tmpRoot = ReactDOMClient.createRoot(document.createElement('div'));
  tmpRoot.render(React.createElement(() => {
    useEffect(() => { resolve(); }, []);
    return React.createElement(BlockNoteView, { editor });
  }));
});
console.log(await editor.blocksToHTMLLossy());

The error thrown is:

Uncaught (in promise) TypeError: t._tiptapEditor.contentComponent is undefined
    Ce ReactRenderUtil.ts:13
    toExternalHTML ReactBlockSpec.tsx:213
    Kt sharedHTMLConversion.ts:70
    serializeNodeInner externalHTMLExporter.ts:66
    serializeFragment index.js:3273
    forEach index.js:250
    serializeFragment index.js:3247
    Kt sharedHTMLConversion.ts:109
    serializeNodeInner externalHTMLExporter.ts:66
    serializeFragment index.js:3273
    forEach index.js:250
    serializeFragment index.js:3247
    Jt sharedHTMLConversion.ts:124
    exportProseMirrorFragment externalHTMLExporter.ts:79
    exportBlocks externalHTMLExporter.ts:90
    blocksToHTMLLossy BlockNoteEditor.ts:907

<clear steps to reproduce are super helpful! Best is to provide an online sandbox, click to create one>

Misc

  • Node version:
  • Package manager:
  • Browser:
  • I'm a sponsor and would appreciate if you could look into this sooner than later 💖
@blx blx added the bug Something isn't working label May 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant