Skip to content

Paragraph

The Paragraph node is the default block-level text container. Every line of regular text in the editor is a paragraph. When you press Enter, a new paragraph is created. It renders as a <p> element in HTML.

Paragraph is included in StarterKit. If you are building a custom setup without StarterKit, add it manually:

import { Editor, Document, Text, Paragraph } from '@domternal/core';
const editor = new Editor({
element: document.getElementById('editor')!,
extensions: [Document, Text, Paragraph],
content: '<p>Hello world</p>',
});
PropertyValue
ProseMirror nameparagraph
TypeNode
Groupblock
Contentinline* (zero or more inline nodes)
HTML tag<p>
Priority1000

The inline* content expression means a paragraph can contain Text nodes and other inline nodes (like Emoji or Mention). An empty paragraph contains no children and renders as an empty <p> tag.

The high priority (1000) ensures Paragraph is the default node type. When ProseMirror needs to create a block node (for example, after pressing Enter or when the document needs at least one child), it picks the highest-priority block node, which is Paragraph.

OptionTypeDefaultDescription
HTMLAttributesRecord<string, unknown>{}HTML attributes added to the <p> element
import { Paragraph } from '@domternal/core';
const CustomParagraph = Paragraph.configure({
HTMLAttributes: { class: 'my-paragraph' },
});

This renders every paragraph as <p class="my-paragraph">.

CommandDescription
setParagraph()Convert the current block to a paragraph
// Convert the current block (heading, blockquote, etc.) to a paragraph
editor.commands.setParagraph();
// With chaining
editor.chain().focus().setParagraph().run();
ShortcutCommand
Mod-Alt-0setParagraph()

This is useful when you have a heading or code block and want to convert it back to a regular paragraph.

{
"type": "paragraph",
"content": [
{ "type": "text", "text": "Hello world" }
]
}

An empty paragraph:

{
"type": "paragraph"
}

@domternal/core - Paragraph.ts