Skip to content

Conversation

@matthewlipski
Copy link
Collaborator

Summary

This PR fixes some visual & DOM inconsistencies between the rendered HTML from a live editor, and the rendered static HTML from exporting blocks.

These differences come mostly from plugins/extensions that use decorations not running when doing an export, as well as a few other fixes due to the HTML being static.

Rationale

One of the use cases of BlockNote is writing content in the editor, taking advantage of its UX and formatting, then exporting that content to HTML so it can be displayed read-only without requiring an editor instance.

However, this is only useful if the static HTML output closely matches what a user sees when editing content in BlockNote.

Changes

  • Fixed alignment issue with check list items.
  • Added transforms to createInternalHTMLSerializer. These are functions which modify the HTML element created from exporting blocks. See internalHTMLSerializer.ts for more info.
  • Added example for comparing a live editor to its exported & rendered static HTML.

Impact

N/A

Testing

TODO (e2e)

Screenshots/Video

N/A

Checklist

  • Code follows the project's coding standards.
  • Unit tests covering the new feature have been added.
  • All existing tests pass.
  • The documentation has been updated to reflect the new feature

Additional Notes

@vercel
Copy link

vercel bot commented Jan 13, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
blocknote Ready Ready Preview Jan 13, 2026 8:03pm
blocknote-website Ready Ready Preview Jan 13, 2026 8:03pm

Comment on lines +145 to +158
// Set of transforms to run on the output HTML element after serializing
// blocks. These are used to add HTML elements, attributes, or class names
// which would normally be done by extensions and plugins. Since these don't
// run when converting blocks to HTML, tranforms are used to mock their
// functionality so that the rendered HTML looks identical to that of a live
// editor.
const transforms: ((element: HTMLElement) => HTMLElement)[] = [
addIndexToNumberedListItems,
makeCheckListItemsReadOnly,
forceToggleBlocksShow,
addTableMinCellWidths,
addTableWrappers,
addTrailingBreakToEmptyInlineContent,
];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fantastic @matthewlipski I'm really happy with how this came out

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants