Skip to content

Empty paragraphs are being removed #986

Closed

Description

@nchanged

Describe the bug
Empty paragraphs are being removed, Which is sometimes crucial for the formatting of the text.

To Reproduce

Load the following content

<p class="bn-inline-content">asdfasdf</p><p class="bn-inline-content">asd</p><p class="bn-inline-content">f</p><p class="bn-inline-content">asdf</p><p class="bn-inline-content"></p><p class="bn-inline-content"></p><p class="bn-inline-content"></p><p class="bn-inline-content"></p><p class="bn-inline-content"></p><p class="bn-inline-content"></p><p class="bn-inline-content"></p><p class="bn-inline-content"></p>

Will result in not preserving the empty lines

Is there a hidden option or something?
Thanks!

Activity

  1. aespinoza96 commented on Aug 6, 2024

    @aespinoza96
    Contributor

    Did you try by adding like a blank space? I know it is not the optimal solution but it might be a workaround

  2. nchanged commented on Aug 14, 2024

    @nchanged
    Author

    that doesn't sound a look a good idea. The formatting will be inconsistent when loading new docs, or if the user just inserts a new line 2 times.

  3. meteorSD commented on Oct 26, 2024

    @meteorSD

    Found a workaround using turndown lib :

    const turndownService = new TurndownService({
      blankReplacement: () => {
        return '&nbsp;';
      },
    });
    const html = await editor.blocksToFullHTML(editor.document);
    const markdown = turndownService.turndown(html);
    
  4. elitan commented on Jan 9, 2025

    @elitan

    @meteorSD do you have a more complete example. I'm not sure I understand how to use the lib for this use case.

    Ideally i want BlockNote to take markdown as input, and mardown as output (in the onChange handler).

    Would be great if you could help out here 🙏

  5. dh4bu commented on Jun 12, 2025

    @dh4bu

    problem still persists

  6. davehuang-tw commented on Jan 22, 2026

    @davehuang-tw

    My approach was to:

    1. Add <br> tag to prevent empty <p></p> getting stripped
    2. Normalize the empty block's content
    export async function htmlToBlockNote(editor: BlockNoteEditor, html: string): Promise<Block[]> {
      if (!html) return []
    
      try {
        // Step 1 - Pre-process: add <br> to empty paragraphs so they're not stripped
        const processedHtml = preserveEmptyParagraphs(html)
        const blocks = await editor.tryParseHTMLToBlocks(processedHtml)
    
        // Step 2 - Post-process: normalize whitespace paragraphs back to empty
        return normalizeEmptyParagraphs(blocks)
      } catch (error) {
        return []
      }
    }
    
    function preserveEmptyParagraphs(html: string): string {
      // Replace empty <p></p> (with or without attributes) with <p...><br></p>
      // Also handles self-closing <p /> tags
      return html
        .replace(/<p([^>]*)><\/p>/gi, '<p$1><br></p>')
        .replace(/<p([^>]*)\/>/gi, '<p$1><br></p>')
    }
    
    const isEmptyOrWhitespaceParagraph = (block: Block): boolean => {
      if (block.type !== 'paragraph') return false
    
      // Type guard: paragraph blocks have inline content array
      const content = block.content as Array<{ type: string; text?: string }> | undefined
      if (!content || content.length === 0) return true
    
      // Check if all content items are whitespace-only text
      return content.every(
        (item) => item.type === 'text' && typeof item.text === 'string' && /^\s*$/.test(item.text)
      )
    }
    
    function normalizeEmptyParagraphs(blocks: Block[]): Block[] {
      return blocks.map((block) => {
        if (isEmptyOrWhitespaceParagraph(block)) {
          return { ...block, content: [] } as Block
        }
        return block
      })
    }
  7. added
    needs-triageIssue has not yet been reviewed or classified by maintainers.
    on Feb 3, 2026
  8. added
    bug:P4Low: Minor issues with little user impact.
    and removed
    needs-triageIssue has not yet been reviewed or classified by maintainers.
    on Feb 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bug:P4Low: Minor issues with little user impact.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions