From zbeyens. The source code is available on GitHub.

Plate
PlatePliteEditorsTemplates
GitHub16kGitHub
DiscordDiscord
    • Stream
    • Copilot
  • Discussion
    • Comments
    • Suggestion
    • Basic Blocks
      • Blockquote
      • Heading
      • Horizontal Rule
    • Callout
    • Code Block
    • Column
    • Date
    • Equation
    • Link
    • List Classic
    • Media
    • MentionElement
    • Table
    • Table of Contents
    • Footnote
    • Toggle
  • Marks
    • Bold
    • Italic
    • Underline
    • Code
    • Highlight
    • Keyboard Input
    • Strikethrough
    • Subscript
    • Superscript
      • Font
      • Line Height
      • Text Align
    • Indent
    • List
      • Exit Break
      • Single Block
      • Trailing Block
    • Autoformat
    • Block Menu
    • Block Placeholder
    • Combobox
      • Emoji
      • MentionElement
      • Slash Command
    • Cursor Overlay
    • Drag & Drop
    • Navigation Feedback
    • Tabbable
    • Toolbar
    • Yjs
    • Multi SelectEditor
    • CSV
    • DOCX
    • HTML
    • Markdown

Callout

PreviousNext

Highlight important information or add special notes.

PlusCallout Element
Loading…
Horizontal RuleCode Block

On This Page

FeaturesKit UsageInstallationAdd KitManual UsageInstallationAdd PluginConfigure PluginPlate PlusPluginsCalloutPluginTransformseditor.plugin(BaseCalloutPlugin).update.insertTypesCalloutElement
Build your editor
Production-ready AI template and reusable components.
Get all-access

Features

  • Customizable callout blocks for highlighting important information
  • Support for different callout variants (e.g., info, warning, error)
  • Ability to set custom icons or emojis for callouts
Report an issue

Kit Usage

Installation

The fastest way to add the callout plugin is with the CalloutKit, which includes pre-configured CalloutPlugin with the Plate UI component.

'use client';
 
import { CalloutPlugin } from '@platejs/callout/react';
import {
  type PlateElementProps,
  PlateElement,
  useEditor,
  useEditorReadOnly,
} from 'platejs/react';
import * as React from 'react';
 
import { Button } from '@/components/ui/button';
 
import { EmojiPicker, EmojiPickerTrigger } from './emoji-picker';
 
const CALLOUT_STORAGE_KEY = 'plate-storage-callout';
 
export function CalloutElement(props: PlateElementProps<typeof CalloutPlugin>) {
  const editor = useEditor();
  const readOnly = useEditorReadOnly();
 
  return (
    <PlateElement
      {...props}
      className="my-1 flex rounded-sm bg-muted p-4 pl-3"
      style={{
        backgroundColor: props.element.backgroundColor,
      }}
      attributes={{
        ...props.attributes,
        'data-plate-open-context-menu': true,
      }}
    >
      <div className="flex w-full gap-2 rounded-md">
        <EmojiPicker
          closeOnSelect
          disabled={readOnly}
          onSelectEmoji={(emoji) => {
            const icon = emoji.skins[0]?.native;
 
            if (!icon) return;
 
            editor.update.nodes.set({ icon }, { at: props.element });
            localStorage.setItem(CALLOUT_STORAGE_KEY, icon);
          }}
        >
          <EmojiPickerTrigger>
            <Button
              disabled={readOnly}
              variant="ghost"
              className="size-6 p-1 text-[18px] select-none hover:bg-muted-foreground/15"
              style={{
                fontFamily:
                  '"Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Noto Color Emoji", "Segoe UI Symbol", "Android Emoji", EmojiSymbols',
              }}
              contentEditable={false}
            >
              {props.element.icon || '💡'}
            </Button>
          </EmojiPickerTrigger>
        </EmojiPicker>
        <div className="w-full">{props.children}</div>
      </div>
    </PlateElement>
  );
}
 
export const CalloutKit = [
  CalloutPlugin.configure({ component: CalloutElement }),
];
'use client';
 
import { CalloutPlugin } from '@platejs/callout/react';
import {
  type PlateElementProps,
  PlateElement,
  useEditor,
  useEditorReadOnly,
} from 'platejs/react';
import * as React from 'react';
 
import { Button } from '@/components/ui/button';
 
import { EmojiPicker, EmojiPickerTrigger } from './emoji-picker';
 
const CALLOUT_STORAGE_KEY = 'plate-storage-callout';
 
export function CalloutElement(props: PlateElementProps<typeof CalloutPlugin>) {



















































  • CalloutElement: Renders callout elements.

Add Kit

Add the kit to your plugins:

import { createPlateEditor } from 'platejs/react';
import { CalloutKit } from '@/components/editor/callout';
 
const editor = createPlateEditor({
  plugins: [
    // ...otherPlugins,
    ...CalloutKit,
  ],
});
import { createPlateEditor } from 'platejs/react';
import { CalloutKit } from '@/components/editor/callout';
 
const editor = createPlateEditor




Manual Usage

Installation

pnpm add @platejs/callout
pnpm add @platejs/callout

Add Plugin

Include CalloutPlugin in your Plate plugins array when creating the editor.

import { CalloutPlugin } from '@platejs/callout/react';
import { createPlateEditor } from 'platejs/react';
 
const editor = createPlateEditor({
  plugins: [
    // ...otherPlugins,
    CalloutPlugin,
  ],
});
import { CalloutPlugin } from '@platejs/callout/react';
import { createPlateEditor } from 'platejs/react';
 
const editor = createPlateEditor({
  plugins: [
    // ...otherPlugins,
    CalloutPlugin,
  ],
});

Configure Plugin

You can configure the CalloutPlugin with a custom component to render callout elements.

import { CalloutPlugin } from '@platejs/callout/react';
import { createPlateEditor } from 'platejs/react';
import { CalloutElement } from '@/components/editor/callout';
 
const editor = createPlateEditor({
  plugins: [
    // ...otherPlugins,
    CalloutPlugin.configure({ component: CalloutElement }),
  ],
});
import { CalloutPlugin } from '@platejs/callout/react';
import







  • component: Assigns CalloutElement to render callout elements.

Plate Plus

  • Insert callouts using the slash command
  • Ability to change the callout emoji
  • Beautifully crafted UI
Get the code

Plugins

CalloutPlugin

Callout element plugin.

Transforms

editor.plugin(BaseCalloutPlugin).update.insert

Insert a callout element into the editor.

Parameters

    Standard insertion options such as at and select.

Types

CalloutElement

import type { CalloutElement } from '@platejs/callout';
import type { CalloutElement } from '@platejs/callout';

CalloutElement is derived from BaseCalloutPlugin. Its schema exposes optional backgroundColor, icon, and variant properties.

Attributes

    The variant of the callout.

    The icon or emoji to display.

const editor = useEditor();
const readOnly = useEditorReadOnly();
return (
<PlateElement
{...props}
className="my-1 flex rounded-sm bg-muted p-4 pl-3"
style={{
backgroundColor: props.element.backgroundColor,
}}
attributes={{
...props.attributes,
'data-plate-open-context-menu': true,
}}
>
<div className="flex w-full gap-2 rounded-md">
<EmojiPicker
closeOnSelect
disabled={readOnly}
onSelectEmoji={(emoji) => {
const icon = emoji.skins[0]?.native;
if (!icon) return;
editor.update.nodes.set({ icon }, { at: props.element });
localStorage.setItem(CALLOUT_STORAGE_KEY, icon);
}}
>
<EmojiPickerTrigger>
<Button
disabled={readOnly}
variant="ghost"
className="size-6 p-1 text-[18px] select-none hover:bg-muted-foreground/15"
style={{
fontFamily:
'"Apple Color Emoji", "Segoe UI Emoji", NotoColorEmoji, "Noto Color Emoji", "Segoe UI Symbol", "Android Emoji", EmojiSymbols',
}}
contentEditable={false}
>
{props.element.icon || '💡'}
</Button>
</EmojiPickerTrigger>
</EmojiPicker>
<div className="w-full">{props.children}</div>
</div>
</PlateElement>
);
}
export const CalloutKit = [
CalloutPlugin.configure({ component: CalloutElement }),
];
({
plugins: [
// ...otherPlugins,
...CalloutKit,
],
});
{ createPlateEditor }
from
'platejs/react'
;
import { CalloutElement } from '@/components/editor/callout';
const editor = createPlateEditor({
plugins: [
// ...otherPlugins,
CalloutPlugin.configure({ component: CalloutElement }),
],
});