For the full runtime — dispatch, ownership, selection context, and custom rule authoring — see the Plugin Input Rules guide. This page is the kit-first entry for markdown shortcuts and text substitutions.
Loading...
Files
components/demo.tsx
'use client';
import * as React from 'react';
import { Plate, usePlateEditor } from 'platejs/react';
import { EditorKit } from '@/components/editor/editor-kit';
import { Editor, EditorContainer } from '@/components/ui/editor';
import { createValue } from './values/demo-values';
export default function Demo({ id }: { id: string }) {
const editor = usePlateEditor({
plugins: EditorKit,
value: createValue(id),
});
return (
<Plate editor={editor}>
<EditorContainer variant="demo">
<Editor />
</EditorContainer>
</Plate>
);
}
Kit Usage
Installation
The fastest way to add common text substitutions is with AutoformatKit.
'use client';
import type { SlateEditor } from 'platejs';
import {
createSlatePlugin,
createTextSubstitutionInputRule,
KEYS,
} from 'platejs';
const isTextSubstitutionBlocked = (editor: SlateEditor) =>
editor.api.some({
match: {
type: [editor.getType(KEYS.codeBlock)],
},
});
const createAutoformatTextSubstitutionRule = ({
patterns,
}: {
patterns: Parameters<typeof createTextSubstitutionInputRule>[0]['patterns'];
}) =>
createTextSubstitutionInputRule({
enabled: ({ editor }) => !isTextSubstitutionBlocked(editor),
patterns,
});
const arrowsRule = createAutoformatTextSubstitutionRule({
patterns: [
{ format: '→', match: '->' },
{ format: '←', match: '<-' },
{ format: '⇒', match: '=>' },
{ format: '⇐', match: ['<=', '≤='] },
],
});
const comparisonsRule = createAutoformatTextSubstitutionRule({
patterns: [
{ format: '≯', match: '!>' },
{ format: '≮', match: '!<' },
{ format: '≥', match: '>=' },
{ format: '≤', match: '<=' },
{ format: '≱', match: '!>=' },
{ format: '≰', match: '!<=' },
],
});
const equalityRule = createAutoformatTextSubstitutionRule({
patterns: [
{ format: '≠', match: '!=' },
{ format: '≡', match: '==' },
{ format: '≢', match: ['!==', '≠='] },
{ format: '≈', match: '~=' },
{ format: '≉', match: '!~=' },
],
});
const fractionsRule = createAutoformatTextSubstitutionRule({
patterns: [
{ format: '½', match: '1/2' },
{ format: '⅓', match: '1/3' },
{ format: '¼', match: '1/4' },
{ format: '⅕', match: '1/5' },
{ format: '⅙', match: '1/6' },
{ format: '⅐', match: '1/7' },
{ format: '⅛', match: '1/8' },
{ format: '⅑', match: '1/9' },
{ format: '⅒', match: '1/10' },
{ format: '⅔', match: '2/3' },
{ format: '⅖', match: '2/5' },
{ format: '¾', match: '3/4' },
{ format: '⅗', match: '3/5' },
{ format: '⅜', match: '3/8' },
{ format: '⅘', match: '4/5' },
{ format: '⅚', match: '5/6' },
{ format: '⅝', match: '5/8' },
{ format: '⅞', match: '7/8' },
],
});
const legalRule = createAutoformatTextSubstitutionRule({
patterns: [
{ format: '™', match: ['(tm)', '(TM)'] },
{ format: '®', match: ['(r)', '(R)'] },
{ format: '©', match: ['(c)', '(C)'] },
],
});
const legalHtmlRule = createAutoformatTextSubstitutionRule({
patterns: [
{ format: '™', match: '™' },
{ format: '®', match: '®' },
{ format: '©', match: '©' },
{ format: '§', match: '§' },
],
});
const operatorsRule = createAutoformatTextSubstitutionRule({
patterns: [
{ format: '±', match: '+-' },
{ format: '‰', match: '%%' },
{ format: '‱', match: ['%%%', '‰%'] },
],
});
const punctuationRule = createAutoformatTextSubstitutionRule({
patterns: [
{ format: '»', match: '>>' },
{ format: '«', match: '<<' },
],
});
const smartQuotesRule = createAutoformatTextSubstitutionRule({
patterns: [
{ format: ['“', '”'], match: '"' },
{ format: ['‘', '’'], match: "'" },
],
});
const subscriptNumbersRule = createAutoformatTextSubstitutionRule({
patterns: [
{ format: '₀', match: '~0' },
{ format: '₁', match: '~1' },
{ format: '₂', match: '~2' },
{ format: '₃', match: '~3' },
{ format: '₄', match: '~4' },
{ format: '₅', match: '~5' },
{ format: '₆', match: '~6' },
{ format: '₇', match: '~7' },
{ format: '₈', match: '~8' },
{ format: '₉', match: '~9' },
],
});
const subscriptSymbolsRule = createAutoformatTextSubstitutionRule({
patterns: [
{ format: '₊', match: '~+' },
{ format: '₋', match: '~-' },
],
});
const superscriptNumbersRule = createAutoformatTextSubstitutionRule({
patterns: [
{ format: '⁰', match: '^0' },
{ format: '¹', match: '^1' },
{ format: '²', match: '^2' },
{ format: '³', match: '^3' },
{ format: '⁴', match: '^4' },
{ format: '⁵', match: '^5' },
{ format: '⁶', match: '^6' },
{ format: '⁷', match: '^7' },
{ format: '⁸', match: '^8' },
{ format: '⁹', match: '^9' },
],
});
const superscriptSymbolsRule = createAutoformatTextSubstitutionRule({
patterns: [
{ format: '°', match: '^o' },
{ format: '⁺', match: '^+' },
{ format: '⁻', match: '^-' },
],
});
const AutoformatShortcutsPlugin = createSlatePlugin({
key: 'autoformatShortcuts',
inputRules: [
legalRule,
legalHtmlRule,
arrowsRule,
comparisonsRule,
equalityRule,
fractionsRule,
operatorsRule,
punctuationRule,
smartQuotesRule,
subscriptNumbersRule,
subscriptSymbolsRule,
superscriptNumbersRule,
superscriptSymbolsRule,
],
});
export const AutoformatKit = [AutoformatShortcutsPlugin];Add Kit
import { createPlateEditor } from 'platejs/react';
import { AutoformatKit } from '@/components/editor/plugins/autoformat-kit';
const editor = createPlateEditor({
plugins: [
// ...otherPlugins,
...AutoformatKit,
],
});Manual Usage
Feature-Owned Markdown Shortcuts
Markdown shortcuts live on the plugins that own those features:
import {
BlockquoteRules,
HeadingRules,
HorizontalRuleRules,
} from '@platejs/basic-nodes';
import {
BlockquotePlugin,
H1Plugin,
HorizontalRulePlugin,
} from '@platejs/basic-nodes/react';
import { CodeBlockRules } from '@platejs/code-block';
import { CodeBlockPlugin } from '@platejs/code-block/react';
import { LinkRules } from '@platejs/link';
import { LinkPlugin } from '@platejs/link/react';
import {
BulletedListRules,
OrderedListRules,
TaskListRules,
} from '@platejs/list';
import { ListPlugin } from '@platejs/list/react';
import { MathRules } from '@platejs/math';
import { EquationPlugin, InlineEquationPlugin } from '@platejs/math/react';
const editor = createPlateEditor({
plugins: [
H1Plugin.configure({
inputRules: [HeadingRules.markdown()],
}),
BlockquotePlugin.configure({
inputRules: [BlockquoteRules.markdown()],
}),
HorizontalRulePlugin.configure({
inputRules: [HorizontalRuleRules.markdown({ variant: '-' })],
}),
CodeBlockPlugin.configure({
inputRules: [CodeBlockRules.markdown({ on: 'match' })],
}),
ListPlugin.configure({
inputRules: [
BulletedListRules.markdown({ variant: '-' }),
OrderedListRules.markdown({ variant: '.' }),
TaskListRules.markdown({ checked: false }),
],
}),
InlineEquationPlugin.configure({
inputRules: [MathRules.markdown({ variant: '$' })],
}),
EquationPlugin.configure({
inputRules: [MathRules.markdown({ on: 'break', variant: '$$' })],
}),
LinkPlugin.configure({
inputRules: [
LinkRules.markdown(),
LinkRules.autolink({ variant: 'paste' }),
LinkRules.autolink({ variant: 'space' }),
LinkRules.autolink({ variant: 'break' }),
],
}),
],
});- Package rule families own the markdown semantics. Kits register explicit rule instances.
Local Text Substitutions
Generic substitutions such as smart quotes, arrows, and fractions are best kept as local copied plugin code:
import {
createSlatePlugin,
createTextSubstitutionInputRule,
} from 'platejs';
const ShortcutsPlugin = createSlatePlugin({
key: 'shortcuts',
inputRules: [
createTextSubstitutionInputRule({
patterns: [{ format: '—', match: '--' }],
}),
],
});
const editor = createPlateEditor({
plugins: [ShortcutsPlugin],
});Fine-Grained Overrides
Rule names are the override unit:
import { ItalicRules } from '@platejs/basic-nodes';
ItalicPlugin.configure({
inputRules: [ItalicRules.markdown({ variant: '_' })],
});