Skip to content
On this page

Block Types & Properties

A block's type affects how it looks and behaves in the editor. Each type also comes with its own set of properties, each having a string value, which further affect the block's appearance and behaviour.

Built-In Block Types

BlockNote includes a number of built-in block types, each with their own set of properties. You can see how they look, both in the editor, and in code using Block objects:

Paragraph

Appearance

image

Type & Props

typescript
type ParagraphBlock = {
  id: string;
  type: "paragraph";
  props: DefaultBlockProps;
  content: InlineContent[];
  children: Block[];
};

Heading

Appearance

image

Type & Props

typescript
type HeadingBlock = {
  id: string;
  type: "heading";
  props: {
    level: "1" | "2" | "3" = "1";
  } & DefaultBlockProps;
  content: InlineContent[];
  children: Block[];
};

level: The heading level, representing a title (level: "1"), heading (level: "2"), and subheading (level: "3").

Bullet List Item

Appearance

image

Type & Props

typescript
type BulletListItemBlock = {
  id: string;
  type: "bulletListItem";
  props: DefaultBlockProps;
  content: InlineContent[];
  children: Block[];
};

Numbered List Item

Appearance

image

Type & Props

typescript
type NumberedListItemBlock = {
  id: string;
  type: "numberedListItem";
  props: DefaultBlockProps;
  content: InlineContent[];
  children: Block[];
};

Default Block Properties

While each type of block can have its own set of properties, there are some properties that all built-in block types have by default, which you can find in the definition for DefaultBlockProps:

typescript
type DefaultBlockProps = {
  backgroundColor: string = "default";
  textColor: string = "default";
  textAlignment: "left" | "center" | "right" | "justify" = "left";
};

backgroundColor: The background color of the block, which also applies to nested blocks.

textColor: The text color of the block, which also applies to nested blocks.

textAlignment: The text alignment of the block.

Custom Block Types

In addition to the default block types that BlockNote offers, you can also make your own custom blocks. Take a look at the demo below, in which we add a custom block containing an image and caption to a BlockNote editor, as well as a custom Slash Menu Item to insert it.

INFO

While custom blocks open a lot of doors for what you can do with BlockNote, we're still working on the API and there are a few limitations for the kinds of blocks you can create.

We'd love to hear your feedback on Github or in our Discord community!

Creating a Custom Block Type

To define a custom block type, we use the createReactBlockSpec function, for which you can see the definition below:

typescript
type PropSchema = Record<
  string,
  {
    default: string;
    values?: string[];
  };
>

function createReactBlockSpec(config: {
  type: string;
  propSchema: PropSchema;
  containsInlineContent: boolean;
  render: (props: {
    block: Block,
    editor: BlockNoteEditor
  }) => JSX.Element;
}): BlockType;

Let's look at our custom image block from the demo, and go over each field in-depth to explain how it works:

typescript
const ImageBlock = createReactBlockSpec({
  type: "image",
  propSchema: {
    src: {
      default: "https://via.placeholder.com/1000",
    },
  },
  containsInlineContent: true,
  render: ({ block }) => (
    <div
      style={{
        display: "flex",
        flexDirection: "column",
      }}>
      <img
        style={{
          width: "100%",
        }}
        src={block.props.src}
        alt={"Image"}
        contentEditable={false}
      />
      <InlineContent />
    </div>
  ),
});

type

Defines the name of the block, in this case, image.

propSchema

This is an object which defines the props that the block should have. In this case, we want the block to have a src prop for the URL of the image, so we add a src key. We also want basic styling options for the image block, so we also add the Default Block Properties using defaultProps. The value of each key is an object with a mandatory default field and an optional values field:

default: Stores the prop's default value, so we use a placeholder image URL for src if no URL is provided.

values: Stores an array of strings that the prop can take. If values is not defined, BlockNote assumes the prop can be any string, which makes sense for src, since it can be any image URL.

containsInlineContent

As we saw in Block Objects, blocks can contain editable rich text which is represented as Inline Content. The containsInlineContent field allows your custom block to contain an editable rich-text field. For the custom image block, we use an inline content field to create our caption, so it's set to true.

render

This is a React component which defines how your custom block should be rendered in the editor, and takes two props:

block: The block that should be rendered.

editor: The BlockNote editor instance that the block is in.

For our custom image block, we use a parent div which contains the image and caption. Since block will always be an image block, we also know it contains a src prop, and can pass it to the child img element.

But what's this InlineContent component? Since we set containsInlineContent to true, it means we want to include an editable rich-text field somewhere in the image block. You should use the InlineContent component to represent this field in your render component. Since we're using it to create our caption, we add it below the img element.

In the DOM, the InlineContent component is rendered as a div by default, but you can make it use a different element by passing as={"elementTag"} as a prop. For example, as={"p"} will make the InlineContent component get rendered to a paragraph.

While the InlineContent component can be put anywhere inside the component you pass to render, you should make sure to only have one. If containsInlineContent is set to false, render shouldn't contain any.

Adding Custom Blocks to the Editor

Now, we need to tell BlockNote to use our custom image block by passing it to the editor in the blockSchema option. Let's again look at the image block from the demo as an example:

typescript
// Creates a new editor instance.
const editor = useBlockNote({
  // Tells BlockNote which blocks to use.
  blockSchema: {
    // Adds all default blocks.
    ...defaultBlockSchema,
    // Adds the custom image block.
    image: ImageBlock,
  },
});

Since we still want the editor to use the Built-In Block Types, we add defaultBlockSchema to our custom block schema. The key which we use for the custom image block is the same string we use for its type. Make sure that this is always the case for your own custom blocks.

And we're done! You now know how to create custom blocks and add them to the editor. Head to Manipulating Blocks to see what you can do with them in the editor.