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

Subscript

PreviousNext

Format inline text below the baseline.

Basic MarksSuperscriptMore Toolbar ButtonPlugin Shortcuts

Subscript is the 'sub' value of Plate's script mark. ScriptPlugin owns both script positions, so switching to superscript replaces the value instead of coordinating two boolean marks.

Loading…
StrikethroughSuperscript

On This Page

FeaturesKit UsageAdd Basic MarksAdd a Toolbar ControlManual UsageOwnershipAPI Reference
Build your editor
Production-ready AI template and reusable components.
Get all-access

Features

  • One script leaf property with 'sub' | 'sup' values, owned by the PLUGINS.script capability.
  • Directional selection affinity.
  • HTML deserialization from sub and vertical-align: sub.
  • <sub> rendering for the 'sub' value.
  • Optional ~x~ input rule through ScriptRules.
Report an issue

Kit Usage

Add Basic Marks

BasicMarksKit includes ScriptPlugin, the subscript input rule, and a mod+comma shortcut.

'use client';
 
import {
  BoldRules,
  CodeRules,
  HighlightRules,
  ItalicRules,
  MarkComboRules,
  ScriptRules,
  StrikethroughRules,
  UnderlineRules,
} from '@platejs/basic-nodes';
import {
  BoldPlugin,
  CodePlugin,
  HighlightPlugin,
  ItalicPlugin,
  KbdPlugin,
  ScriptPlugin,
  StrikethroughPlugin,
  UnderlinePlugin,
} from '@platejs/basic-nodes/react';
 
import { CodeLeaf } from '@/components/editor/code';
import { HighlightLeaf } from '@/components/editor/highlight';
import { KbdLeaf } from '@/components/editor/kbd';
 
export const BasicMarksKit = [
  BoldPlugin.configure({
    inputRules: [
      BoldRules.markdown({ variant: '*' }),
      BoldRules.markdown({ variant: '_' }),
      MarkComboRules.markdown({ variant: 'boldItalic' }),
      MarkComboRules.markdown({ variant: 'boldUnderline' }),
      MarkComboRules.markdown({ variant: 'boldItalicUnderline' }),
      MarkComboRules.markdown({ variant: 'italicUnderline' }),
    ],
  }),
  ItalicPlugin.configure({
    inputRules: [
      ItalicRules.markdown({ variant: '*' }),
      ItalicRules.markdown({ variant: '_' }),
    ],
  }),
  UnderlinePlugin.configure({
    inputRules: [UnderlineRules.markdown()],
  }),
  CodePlugin.configure({
    component: CodeLeaf,
    inputRules: [CodeRules.markdown()],
    shortcuts: { toggle: { keys: 'mod+e' } },
  }),
  StrikethroughPlugin.configure({
    inputRules: [StrikethroughRules.markdown()],
    shortcuts: { toggle: { keys: 'mod+shift+x' } },
  }),
  ScriptPlugin.configure({
    inputRules: [
      ScriptRules.markdown({ value: 'sub' }),
      ScriptRules.markdown({ value: 'sup' }),
    ],
    shortcuts: {
      subscript: {
        keys: 'mod+comma',
        handler: ({ editor }) => {
          editor.plugin(ScriptPlugin).update.toggle('sub');
        },
      },
      superscript: {
        keys: 'mod+period',
        handler: ({ editor }) => {
          editor.plugin(ScriptPlugin).update.toggle('sup');
        },
      },
    },
  }),
  HighlightPlugin.configure({
    component: HighlightLeaf,
    inputRules: [
      HighlightRules.markdown({ variant: '==' }),
      HighlightRules.markdown({ variant: '≡' }),
    ],
    shortcuts: { toggle: { keys: 'mod+shift+h' } },
  }),
  KbdPlugin.configure({ component: KbdLeaf }),
] as const;
'use client';
 
import {
  BoldRules,
  CodeRules,
  HighlightRules,
  ItalicRules,
  MarkComboRules,
  ScriptRules,
  StrikethroughRules,
  UnderlineRules,
} from '@platejs/basic-nodes';
import {
  BoldPlugin,
  CodePlugin,
  HighlightPlugin,
  ItalicPlugin,
  KbdPlugin,
  ScriptPlugin,
  StrikethroughPlugin,
  UnderlinePlugin,
} from '@platejs/basic-nodes/react';
 
import { CodeLeaf } from '@/components/editor/code';
import { HighlightLeaf } from '@/components/editor/highlight';




























































import { createPlateEditor } from 'platejs/react';
 
import { BasicMarksKit } from '@/components/editor/basic-marks';
 
export const editor = createPlateEditor({
  plugins: [...BasicMarksKit],
});
import { createPlateEditor } from 'platejs/react';
 
import { BasicMarksKit } from '@/components/editor/basic-marks';
 
export const editor = createPlateEditor({

Add a Toolbar Control

Pass the shared plugin and the subscript value to MarkToolbarButton.

import { ScriptPlugin } from '@platejs/basic-nodes/react';
import { SubscriptIcon } from 'lucide-react';
 
import { MarkToolbarButton } from '@/components/editor/mark-toolbar-button';
 
export function SubscriptToolbarButton() {
  return (
    <MarkToolbarButton
      plugin={ScriptPlugin}
      value="sub"
      tooltip="Subscript"
    >
      <SubscriptIcon />
    </MarkToolbarButton>
  );
}

Manual Usage

Install the mark package.

pnpm add @platejs/basic-nodes
pnpm add @platejs/basic-nodes

Add the shared script plugin and configure only the input rule you need.

import { ScriptRules } from '@platejs/basic-nodes';
import { ScriptPlugin } from '@platejs/basic-nodes/react';
import { createPlateEditor } from 'platejs/react';
 
export const editor = createPlateEditor({
  plugins: [
    ScriptPlugin.configure({
      inputRules: [ScriptRules.markdown({ value: 'sub' })],
    }),
  ],
});
import { ScriptRules } from '@platejs/basic-nodes';
import { ScriptPlugin } from '@platejs/basic-nodes/react';
import { createPlateEditor } from 'platejs/react';
 
export const editor = createPlateEditor({
  plugins: [
    ScriptPlugin.configure({
      inputRules: [ScriptRules.markdown({ value: 'sub' })],
    }),
  ],
});

Toggle subscript from application code with the typed value.

editor.update.script.toggle('sub');
editor.update.script.toggle('sub');

Ownership

SurfaceOwnerWhat It Does
BaseScriptPlugin@platejs/basic-nodesDeclares the enum mark, HTML codec, selection rule, and typed toggle.
ScriptPlugin@platejs/basic-nodes/reactRenders 'sub' as <sub> and 'sup' as <sup>.
ScriptRules.markdown@platejs/basic-nodesCreates a value-aware ~x~ or ^x^ input rule.
BasicMarksKitRegistryConfigures both input rules and shortcuts.
MarkToolbarButtonRegistry UIToggles the requested script value.

API Reference

APIUse
editor.plugin(ScriptPlugin).schema.keyThe configured text property (default: script).
ScriptPluginShared React plugin for subscript and superscript.
ScriptRules.markdown({ value: 'sub' })Creates the subscript input rule.
editor.update.script.toggle('sub')Applies subscript or removes it when already active.
import { KbdLeaf } from '@/components/editor/kbd';
export const BasicMarksKit = [
BoldPlugin.configure({
inputRules: [
BoldRules.markdown({ variant: '*' }),
BoldRules.markdown({ variant: '_' }),
MarkComboRules.markdown({ variant: 'boldItalic' }),
MarkComboRules.markdown({ variant: 'boldUnderline' }),
MarkComboRules.markdown({ variant: 'boldItalicUnderline' }),
MarkComboRules.markdown({ variant: 'italicUnderline' }),
],
}),
ItalicPlugin.configure({
inputRules: [
ItalicRules.markdown({ variant: '*' }),
ItalicRules.markdown({ variant: '_' }),
],
}),
UnderlinePlugin.configure({
inputRules: [UnderlineRules.markdown()],
}),
CodePlugin.configure({
component: CodeLeaf,
inputRules: [CodeRules.markdown()],
shortcuts: { toggle: { keys: 'mod+e' } },
}),
StrikethroughPlugin.configure({
inputRules: [StrikethroughRules.markdown()],
shortcuts: { toggle: { keys: 'mod+shift+x' } },
}),
ScriptPlugin.configure({
inputRules: [
ScriptRules.markdown({ value: 'sub' }),
ScriptRules.markdown({ value: 'sup' }),
],
shortcuts: {
subscript: {
keys: 'mod+comma',
handler: ({ editor }) => {
editor.plugin(ScriptPlugin).update.toggle('sub');
},
},
superscript: {
keys: 'mod+period',
handler: ({ editor }) => {
editor.plugin(ScriptPlugin).update.toggle('sup');
},
},
},
}),
HighlightPlugin.configure({
component: HighlightLeaf,
inputRules: [
HighlightRules.markdown({ variant: '==' }),
HighlightRules.markdown({ variant: '≡' }),
],
shortcuts: { toggle: { keys: 'mod+shift+h' } },
}),
KbdPlugin.configure({ component: KbdLeaf }),
] as const;
plugins: [
...
BasicMarksKit],
});
import { ScriptPlugin } from '@platejs/basic-nodes/react';
import { SubscriptIcon } from 'lucide-react';
 
import { MarkToolbarButton } from '@/components/editor/mark-toolbar-button';
 
export function SubscriptToolbarButton() {
  return (
    <MarkToolbarButton
      plugin={ScriptPlugin}
      value="sub"
      tooltip="Subscript"
    >
      <SubscriptIcon />
    </MarkToolbarButton>
  );
}