Plugin Components

Learn how to create and style custom components for Plate plugins.

By default, Plate plugins are headless, meaning all nodes will be rendered as plain text. This guide will show you how to create and style custom components for your editor.

Plate UI

Unless you prefer to build everything from scratch, we recommend using Plate UI to get started. Plate UI is a collection of components that you can copy into your app and modify to suit your needs.

In most respects, the process of adding components to your editor is the same regardless of whether you use Plate UI or build your own components from scratch.

Defining Components

The simplest way of defining a component is using PlateElement or PlateLeaf as a wrapper for your content. This ensures that the correct props are applied to your HTML element as required by Slate.

Note that the children prop must be rendered unconditionally for the editor to work correctly, including for void nodes.

Element

import { PlateElement, PlateElementProps } from '@udecode/plate/react';
 
export function BlockquoteElement({
  className,
  children,
  ...props
}: PlateElementProps) {
  return (
    <PlateElement asChild className={className} {...props}>
      <blockquote>{children}</blockquote>
    </PlateElement>
  );
}

Leaf

import { PlateLeaf, PlateLeafProps } from '@udecode/plate/react';
 
export function CodeLeaf({ className, children, ...props }: PlateLeafProps) {
  return (
    <PlateLeaf asChild className={className} {...props}>
      <code>{children}</code>
    </PlateLeaf>
  );
}

Styling with CSS

We recommend styling components using Tailwind CSS, which is the pattern used by Plate UI. However, you can also use a global CSS file to style nodes based on the class names generated by Slate.

For each node, Slate generates a class name with slate- followed by the node type. For example, paragraph nodes can be styled as:

.slate-p {
  margin-bottom: 1rem;
}

Register Components

There are two ways to register your components with Plate plugins.

Plugin Options

Register a component using node.component option:

const ParagraphPlugin = createPlatePlugin({
  node: {
    component: ParagraphElement,
  },
});
 
// OR
const ParagraphPlugin = BaseParagraphPlugin.withComponent(ParagraphElement)

Editor Options

Specify components for plugin keys using override.components:

const editor = createPlateEditor({
  plugins: [ParagraphPlugin, LinkPlugin],
  override: {
    components: {
      [ParagraphPlugin.key]: ParagraphElement,
      [LinkPlugin.key]: LinkElement,
      // ...other components
    },
  },
});