Skip to content

Tables break when using tryParseHTMLToBlocks with previously exported HTML #1632

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

Closed
1 task
guillepujol13 opened this issue Apr 23, 2025 · 6 comments
Closed
1 task
Assignees
Labels
bug Something isn't working

Comments

@guillepujol13
Copy link

Describe the bug
When using tryParseHTMLToBlocks to build blocks from previously generated editor HTML, tables break and appear in a strange, incorrect format. Instead of keeping their original structure, they are rendered as plain paragraphs or separate blocks, losing all table layout and semantics.

To Reproduce

  1. Create a table in the editor.
  2. Export the editor content as HTML.
  3. Re-import that HTML using tryParseHTMLToBlocks.
  4. Notice how the table no longer appears as a table and the structure is broken.

Expected behavior
The table should be correctly parsed into blocks that retain the visual and semantic table structure.

Misc

  • Node version: 18
  • Package manager: yarn
  • Browser: chrome
  • I'm a sponsor and would appreciate if you could look into this sooner than later 💖
Image
@guillepujol13 guillepujol13 added the bug Something isn't working label Apr 23, 2025
@guillepujol13
Copy link
Author

Hey @matthewlipski ! Thanks for taking a look at this 🙏
Just wondering if there’s any update on the issue, or if there's any known workaround we could use in the meantime.

Thanks again for your time!

@matthewlipski
Copy link
Collaborator

Hey, just a question - are you using blocksToFullHTML or blocksToHTMLLossy to do the conversion to HTML?

@matthewlipski
Copy link
Collaborator

Had a quick look on the website and it seems to be working ok there:

rec.mov

Also tried with edge cases like multiple consecutive empty single-cell tables and multiple consecutive filled tables.

Maybe it's something specific happening on your end? Could you show your:

  1. Original blocks (JSON) that are being converted to HTML
  2. The converted HTML
  3. The final blocks (JSON) that the HTML is converted back into
  4. The code that you're using for the conversion

@guillepujol13
Copy link
Author

Hi, thanks for the quick reply.

Here’s all the information you requested — along with some context that might help narrow it down:


🧩 Original Blocks (before any conversion):

[
    {
        "id": "f83be25f-5c96-49d6-938b-32596b2c7f0c",
        "type": "table",
        "props": {
            "textColor": "default",
            "backgroundColor": "default"
        },
        "content": {
            "type": "tableContent",
            "rows": [
                {
                    "cells": [
                        [
                            {
                                "type": "text",
                                "text": "1",
                                "styles": {}
                            }
                        ],
                        [
                            {
                                "type": "text",
                                "text": "2",
                                "styles": {}
                            }
                        ],
                        [
                            {
                                "type": "text",
                                "text": "3",
                                "styles": {}
                            }
                        ]
                    ]
                },
                {
                    "cells": [
                        [
                            {
                                "type": "text",
                                "text": "4",
                                "styles": {}
                            }
                        ],
                        [],
                        [
                            {
                                "type": "text",
                                "text": "6",
                                "styles": {}
                            }
                        ]
                    ]
                }
            ]
        },
        "children": []
    },
    {
        "id": "4f083dc1-334c-4d3b-a99c-e5a581740590",
        "type": "paragraph",
        "props": {
            "textColor": "default",
            "backgroundColor": "default",
            "textAlignment": "left"
        },
        "content": [],
        "children": []
    }
]

Conversion code used:

// To HTML
const handleChange = async () => {
  const html = await editor.blocksToHTMLLossy(editor.document)
  onChange?.(html)
}

// From HTML (initial load)
async function loadInitialHTML() {
  const blocks = await editor.tryParseHTMLToBlocks(initialValue ?? '')
  editor.replaceBlocks(editor.document, blocks)
}

HTML after conversion (onChange):

<table>
  <tbody>
    <tr>
      <td colspan="1" rowspan="1"><p>1</p></td>
      <td colspan="1" rowspan="1"><p>2</p></td>
      <td colspan="1" rowspan="1"><p>3</p></td>
    </tr>
    <tr>
      <td colspan="1" rowspan="1"><p>4</p></td>
      <td colspan="1" rowspan="1"><p></p></td>
      <td colspan="1" rowspan="1"><p>6</p></td>
    </tr>
  </tbody>
</table>
<p></p>

Final blocks after reconverting HTML:

[
    {
        "id": "10408338-74ed-40b0-ab05-b025182bfcf1",
        "type": "table",
        "props": {
            "textColor": "default",
            "backgroundColor": "default"
        },
        "content": {
            "type": "tableContent",
            "rows": [
                {
                    "cells": [
                        []
                    ]
                }
            ]
        },
        "children": [
            {
                "id": "e417a6e4-9a67-491f-bb25-234ae5ae849f",
                "type": "paragraph",
                "props": {
                    "textColor": "default",
                    "backgroundColor": "default",
                    "textAlignment": "left"
                },
                "content": [
                    {
                        "type": "text",
                        "text": "1",
                        "styles": {}
                    }
                ],
                "children": []
            },
            {
                "id": "b2101fc9-b13a-457b-b8e3-e8c8f87b1486",
                "type": "table",
                "props": {
                    "textColor": "default",
                    "backgroundColor": "default"
                },
                "content": {
                    "type": "tableContent",
                    "rows": [
                        {
                            "cells": [
                                []
                            ]
                        }
                    ]
                },
                "children": [
                    {
                        "id": "fd8d024f-bcc6-42c9-a5ab-c593f226175e",
                        "type": "paragraph",
                        "props": {
                            "textColor": "default",
                            "backgroundColor": "default",
                            "textAlignment": "left"
                        },
                        "content": [
                            {
                                "type": "text",
                                "text": "2",
                                "styles": {}
                            }
                        ],
                        "children": []
                    },
                    {
                        "id": "22daa17a-b031-4442-8aff-7742825b9f87",
                        "type": "table",
                        "props": {
                            "textColor": "default",
                            "backgroundColor": "default"
                        },
                        "content": {
                            "type": "tableContent",
                            "rows": [
                                {
                                    "cells": [
                                        []
                                    ]
                                }
                            ]
                        },
                        "children": [
                            {
                                "id": "982e3d98-11f4-4206-ad28-2174c48d5377",
                                "type": "paragraph",
                                "props": {
                                    "textColor": "default",
                                    "backgroundColor": "default",
                                    "textAlignment": "left"
                                },
                                "content": [
                                    {
                                        "type": "text",
                                        "text": "3",
                                        "styles": {}
                                    }
                                ],
                                "children": []
                            },
                            {
                                "id": "f3ee5211-8acc-4aa4-badc-070a9fb8c8e9",
                                "type": "table",
                                "props": {
                                    "textColor": "default",
                                    "backgroundColor": "default"
                                },
                                "content": {
                                    "type": "tableContent",
                                    "rows": [
                                        {
                                            "cells": [
                                                []
                                            ]
                                        }
                                    ]
                                },
                                "children": [
                                    {
                                        "id": "8413734b-18fb-4752-92fa-8ff2f5dd0b7d",
                                        "type": "paragraph",
                                        "props": {
                                            "textColor": "default",
                                            "backgroundColor": "default",
                                            "textAlignment": "left"
                                        },
                                        "content": [
                                            {
                                                "type": "text",
                                                "text": "4",
                                                "styles": {}
                                            }
                                        ],
                                        "children": []
                                    },
                                    {
                                        "id": "cd83d5bc-0252-4ba6-adec-b2ac6a4b40a5",
                                        "type": "table",
                                        "props": {
                                            "textColor": "default",
                                            "backgroundColor": "default"
                                        },
                                        "content": {
                                            "type": "tableContent",
                                            "rows": [
                                                {
                                                    "cells": [
                                                        [],
                                                        []
                                                    ]
                                                }
                                            ]
                                        },
                                        "children": [
                                            {
                                                "id": "55ae023e-fbd5-4a3d-9b3b-92d0d10491f1",
                                                "type": "paragraph",
                                                "props": {
                                                    "textColor": "default",
                                                    "backgroundColor": "default",
                                                    "textAlignment": "left"
                                                },
                                                "content": [
                                                    {
                                                        "type": "text",
                                                        "text": "6",
                                                        "styles": {}
                                                    }
                                                ],
                                                "children": []
                                            }
                                        ]
                                    }
                                ]
                            }
                        ]
                    }
                ]
            }
        ]
    }
]

Additional context:

Here’s the strange part: if I use the deploy from one week ago, everything still works fine. But if I run the project locally or create a new deploy — without changing anything in the code or package versions — this bug appears.

This leads me to think that something must have changed internally or externally in a dependency, or some runtime behavior, because our project codebase has not changed in any way that touches this.

Let me know if I can help debug this further from my side — I’m happy to test or isolate anything that might help!

@nperez0111
Copy link
Contributor

nperez0111 commented Apr 25, 2025

You are using the lossy HTML export, which, as the name implies, is lossy and may not be interpreted by the editor properly.

If you want something that is compatible with the editor, use the editor.blocksToFullHTML which would be fully interpret-able by the editor

@YousefED
Copy link
Collaborator

If it's just about loading / saving editor content, we recommend storing json and following this approach; https://www.blocknotejs.org/examples/backend/saving-loading

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

4 participants