Concepts

Nodes

11min

The most important types are the Node objects:

  • A root-level Editor node that contains the entire document's content.
  • Container Element nodes which have semantic meaning in your domain.
  • And leaf-level Text nodes which contain the document's text.

These three interfaces are combined together to form a treeβ€”just like the DOM. For example, here's a simple plaintext value:

JS
ο»Ώ

Mirroring the DOM as much as possible is one of Slate's principles. People use the DOM to represent documents with richtext-like structures all the time. Mirroring the DOM helps make the library familiar for new users, and it lets us reuse battle-tested patterns without having to reinvent them ourselves.

πŸ€– The following content on Mozilla's Developer Network may help you learn more about the corresponding DOM concepts:

A Slate document is a nested and recursive structure. In a document, elements can have children nodesβ€”all of which may have children nodes without limit. The nested and recursive structure enables you to model simple behaviors such as user mentions and hashtags or complex behaviors such as tables and figures with captions.

Editor

The top-level node in a Slate document is the Editor itself. It encapsulates all of the richtext "content" of the document. Its interface is:

TypeScript
ο»Ώ

We'll cover its functionality later, but the important part as far as nodes are concerned is its children property which contains a tree of Node objects.

Element

Elements make up the middle layers of a richtext document. They are the nodes that are custom to your own domain. Their interface is:

TypeScript
ο»Ώ

You can define custom elements for any type of content you want. For example you might have paragraphs and quotes in your data model which are differentiated by a type property:

JS
ο»Ώ

It's important to note that you can use any custom properties you want. The type property in that example isn't something Slate knows or cares about. If you were defining your own "link" nodes, you might have a url property:

JS
ο»Ώ

Or maybe you want to give all of your nodes ID an property:

JS
ο»Ώ

All that matters is that elements always have a children property.

Blocks vs. Inlines

Depending on your use case, you might want to define another behavior for Element nodes which determines their editing "flow".

All elements default to being "block" elements. They each appear separated by vertical space, and they never run into each other.

But in certain cases, like for links, you might want to make them "inline" flowing elements instead. That way they live at the same level as text nodes, and flow.

πŸ€– This is a concept borrowed from the DOM's behavior, see Block Elements and Inline Elements.

You can define which nodes are treated as inline nodes by overriding the editor.isInline function. (By default it always returns false.) Note that inline nodes cannot be the first or last child of a parent block, nor can it be next to another inline node in the children array. Slate will automatically space these with { text: '' } children by default with normalizeNodeο»Ώ.

Elements can either contain block elements or inline elements intermingled with text nodes as children. But elements cannot contain some children that are blocks and some that are inlines.

Voids

Similar to blocks and inlines, there is another element-specific behavior you can define depending on your use case: their "void"-ness.

Elements default to being non-void, meaning that their children are fully editable as text. But in some cases, like for images, you want to ensure that Slate doesn't treat their content as editable text, but instead as a black box.

πŸ€– This is a concept borrowed from the HTML spec, see Void Elements.

You can define which elements are treated as void by overriding the editor.isVoid function. (By default it always returns false.)

Text

Text nodes are the lowest-level nodes in the tree, containing the text content of the document, along with any formatting. Their interface is:

TypeScript
ο»Ώ

For example, a string of bold text:

JS
ο»Ώ

Text nodes too can contain any custom properties you want, and that's how you implement custom formatting like bold, italic, code, etc.

Updated 08 May 2024
Doc contributor
Did this page help you?