@platejs/docx-io
Bug Fixes
-
- Fix tables nested in table cells missing from the exported DOCX. (#5232)
- Fix invalid DOCX output for a table cell that holds only a skipped image, such as a WebP.
@platejs/docx-io
Features
-
- Add
paragraphSpacingandheadingSpacingtoexportToDocx,exportEditorToDocx,editor.api.docxExport.exportToBlob,editor.tf.docxExport.exportAndDownloadandhtmlToDocxBlobto set the space Word adds around paragraphs and headings, in twentieths of a point. Without them the file is unchanged. (#5233)
- Add
@platejs/docx-io
Features
-
- Add
pageNumbertoexportToDocx,exportEditorToDocx,editor.api.docxExport.exportToBlobandeditor.tf.docxExport.exportAndDownloadto number the pages in a footer. (#5193)
- Add
@platejs/ai
Bug Fixes
- Updated
@platejs/markdown.
@platejs/core
Bug Fixes
-
Upgrade to slate 0.142.1, slate-dom 0.142.0, slate-react 0.142.0 and slate-hyperscript 0.138.3. (#5172)
-
Upgrade to slate 0.146.0, slate-dom 0.146.0 and slate-react 0.145.1. (#5190)
@platejs/markdown
Bug Fixes
-
- Apply
allowedNodes,disallowedNodesandallowNodeto the children of bold, italic and strikethrough, sodisallowedNodes: ['a']also removes a link inside**…**. AnallowedNodeslist now needstext, and any inline type such asa, listed to keep that content inside these marks, as it already does outside them. (#5185)
- Apply
-
- Keep HTML that has no rule as source: unknown tags, raw
htmlnodes and HTML comments deserialize as a text leaf withrawHtml: trueand serialize back unescaped. Before,<b>x</b>came back as\<b>x\</b>, and comments were dropped. (#5179)
- Keep HTML that has no rule as source: unknown tags, raw
-
Keep Markdown inside unknown tags:
<b>`code`</b>no longer loses its backticks, and a list or paragraph inside a block tag such as<details>keeps the blank lines around it, so it still renders as Markdown. -
- Deserialize reference links and images (
[text][id],[id][],[id],![alt][id]) asaandimgnodes using the matching definition's URL. They were dropped before, so a paragraph holding only a reference link came back empty. (#5177)
- Deserialize reference links and images (
-
- Stop serializing the empty text around inline elements (links, mentions, footnote references) as a zero-width space. Only an empty paragraph is written as
now, so Markdown output no longer carries invisible characters at the start or end of a paragraph. (#5178)
- Stop serializing the empty text around inline elements (links, mentions, footnote references) as a zero-width space. Only an empty paragraph is written as
platejs
Bug Fixes
- Updated
@platejs/core,@platejs/slate,@platejs/utils.
@platejs/slate
Bug Fixes
-
Bring the bundled history plugin up to date with slate-history: (#5172)
withoutSaving,withoutMerging,withMergingandwithNewBatchrestore their flags when the callback throws, so one failed transform no longer stops history from recording.- A nested
withNewBatchkeeps the enclosing batch's split. - An edit no longer merges into the previous undo step just because another operation, such as a selection change, ran earlier in the same tick.
- Inside
withoutMerging, a transform's normalization stays in the same undo step as the transform, so undoing it no longer leaves an unnormalized document behind.
editor.hasRangeandeditor.api.hasRangenow share one implementation built on slate'shasRange, and still returnfalsefor a missing range. -
Bring the bundled history plugin up to date with slate-history 0.144.0: (#5190)
- Add
editor.tf.setChildren(children), which applies an outside document through operations instead of replacingeditor.children, so the selection, refs and history stay valid. Each call is its own undo step, separate from typing before and after it. - Undo and redo now account for changes applied with
editor.tf.withoutSaving. Saved steps are moved past each unsaved operation, so a block inserted above earlier typing, or text inserted before it, no longer makes undo remove the wrong characters. Steps whose content was removed, or that can no longer be applied, are dropped.
- Add
-
Upgrade to slate 0.142.1, slate-dom 0.142.0, slate-react 0.142.0 and slate-hyperscript 0.138.3. (#5172)
-
Upgrade to slate 0.146.0, slate-dom 0.146.0 and slate-react 0.145.1. (#5190)
-
Updated
slate,slate-dom,slate-react. (cb4f514)
@platejs/utils
Bug Fixes
- Updated
@platejs/core,@platejs/slate.
v53.3.17...v53.3.18 · By @dylans, @ybai08, @github-actions[bot]
@platejs/ai
Bug Fixes
- Updated
@platejs/markdown.
@platejs/docx-io
Bug Fixes
-
Fix
<br>export: Word for Mac no longer labels it as a text wrapping break, and Word no longer stretches the justified line that ends with it, a setting that applies to the whole document. (#5161) -
Fix DOCX export losing marks on text that carries several marks (for example bold and italic) and leaking a mark onto the text that follows it (#5150)
@platejs/markdown
Bug Fixes
-
Fix email autolinks losing later Markdown content when MDX is configured on Plate's default Markdown parser. Keep ordinary link and image URLs and existing JSX formatting when parsing autolinks. (#5159)
-
- Apply
disallowedNodesto HTML and MDX elements by the key of their deserialize rule, so withremark-mdx,disallowedNodes: ['a']also removes<a href>. (#5141)
- Apply
v53.3.16...v53.3.17 · By @vincent69001, @SahinurDEV, @zbeyens
@platejs/ai
Bug Fixes
- Updated
@platejs/markdown.
@platejs/markdown
Bug Fixes
-
- Deserialize
<ul>and<ol>inside table cells as indent-list paragraphs, including nested lists,<ol start>, and checkbox todo items. (#5139)
- Deserialize
- Serialize list paragraphs inside table cells as
<ul>and<ol>instead of breaking the table row. - Serialize line breaks inside table cells as
<br/>. - Fix inline HTML
<a href>links losing their URL on deserialize.
platejs
Bug Fixes
- Updated
@platejs/core,@platejs/slate,@platejs/utils.
@platejs/slate
Bug Fixes
- Updated
slate-react. (a9bfa84)
@platejs/utils
Bug Fixes
- Updated
@platejs/core,@platejs/slate.
v53.3.14...v53.3.15 · By @OrbitingBucket, @github-actions[bot]
@platejs/core
Bug Fixes
- Keep HTML element transforms in their source document during DOCX paste. (#5131)
platejs
Bug Fixes
- Updated
@platejs/core,@platejs/utils.
@platejs/utils
Bug Fixes
- Updated
@platejs/core.
@platejs/ai
Bug Fixes
- Updated
@platejs/markdown.
@platejs/markdown
Bug Fixes
- Preserve link text and destinations when serializing Markdown. (#5120)
@platejs/math
Bug Fixes
- Preserve equation text during HTML import, normalization and rendering, including persisted numeric and boolean values. Display missing or unsupported values as empty. (#5120)
@platejs/core
Bug Fixes
- Parse HTML strings in inert documents during deserialization (#5117)
platejs
Bug Fixes
- Updated
@platejs/core,@platejs/utils.
@platejs/utils
Bug Fixes
- Updated
@platejs/core.
@platejs/core
Bug Fixes
- Preserve HTML escaping when serializing editor content (
1af4d23)
@platejs/docx-io
Bug Fixes
- Preserve equation output while ignoring unrelated XML (
dfe6805)
platejs
Bug Fixes
- Updated
@platejs/core,@platejs/slate,@platejs/utils.
@platejs/slate
Bug Fixes
- Updated
slate-react. (12a034f)
@platejs/utils
Bug Fixes
- Updated
@platejs/core,@platejs/slate.
@platejs/core
Bug Fixes
- Fix multiple
usePlateEditorinstances crashing when initialized with the same static value (#5110)
platejs
Bug Fixes
- Updated
@platejs/core,@platejs/utils.
@platejs/utils
Bug Fixes
- Updated
@platejs/core.
@platejs/core
Bug Fixes
- Fix multiline plain-text pastes crashing when
maxLengthtruncates across blocks (#5101)
platejs
Bug Fixes
- Updated
@platejs/core,@platejs/utils.
@platejs/utils
Bug Fixes
- Updated
@platejs/core.
@platejs/core
Bug Fixes
- Fix
editor.api.html.deserializereturning unwrapped text nodes at the root for inline-only HTML (#5098)
platejs
Bug Fixes
- Updated
@platejs/core,@platejs/utils.
@platejs/utils
Bug Fixes
- Updated
@platejs/core.
platejs
Bug Fixes
- Updated
@platejs/core,@platejs/slate,@platejs/utils.
@platejs/slate
Bug Fixes
- Updated
slate. (91f4c0c)
@platejs/utils
Bug Fixes
- Updated
@platejs/core,@platejs/slate.
@platejs/ai
Bug Fixes
- Updated
@platejs/markdown.
@platejs/markdown
Bug Fixes
- Keep custom inline elements inside a table cell's paragraph when deserializing markdown. The cell deserializer recognised only
inlineEquationas inline, so any other custom inline element was hoisted out of the paragraph and became its sibling. The cell serializer then separated those siblings with<br/>, and a second round trip turned that into a newline — silently destroying the element. The check now asks the editor whether the node is inline, which is the same answer the plugin configuration already holds. (#5068)
platejs
Bug Fixes
- Updated
@platejs/core,@platejs/slate,@platejs/utils.
@platejs/slate
Bug Fixes
- Updated
slate,slate-dom,slate-react. (279fdae)
@platejs/utils
Bug Fixes
- Updated
@platejs/core,@platejs/slate.
v53.3.2...v53.3.3 · By @WilliamPeralta, @github-actions[bot]
@platejs/docx-io
Bug Fixes
-
Skip remote image URLs by default during DOCX export. (#5053)
Migration: Convert trusted remote images to data URIs before calling
htmlToDocxBlob, or passallowRemoteImages: trueonly when the HTML source is trusted.
@platejs/link
Bug Fixes
df0996f810d69f1d6660dbeac2a4cceda1d5e6dd– Fix Floating Link: ignore the Safari + Japanese IME composition-commit Enter (keyCode === 229, whereisComposingis false) so it no longer submits the link mid-composition. Mirrors the Enter guard already used incmdk.
@platejs/ai
Features
34fdca42f73e7dd30d94db31058c28662dbb9212– Support AI SDK v7 chat helper types.
@platejs/core
Bug Fixes
- Keep dependent Plate packages aligned with core patch releases. (#5046)
platejs
Bug Fixes
- Updated
@platejs/core,@platejs/utils.
@platejs/utils
Bug Fixes
- Updated
@platejs/core.
@platejs/ai
Bug Fixes
- Updated
@platejs/selection.
@platejs/selection
Bug Fixes
- Fix block selection copy and cut in Safari by writing selected blocks to the native clipboard event. (#5018)
@platejs/ai
Bug Fixes
- Updated
@platejs/markdown.
@platejs/markdown
Bug Fixes
- Fix markdown deserialization from crashing on malformed HTML-like MDX input. (#5016)
@platejs/list
Bug Fixes
- Fix ordered paragraph lists continuing numbering from numbered headings. (#5011)
@platejs/core
Bug Fixes
- Fix complex leaf and text renderers triggering React hook-order warnings when marks change. (#5009)
platejs
Bug Fixes
- Updated
@platejs/core,@platejs/utils.
@platejs/utils
Bug Fixes
- Updated
@platejs/core.
@platejs/ai
Bug Fixes
- Updated
@platejs/markdown.
@platejs/markdown
Bug Fixes
- Fix MDX fallback deserialization for GFM tables containing plain less-than text. (#5007)
@platejs/docx-io
Features
-
Forward two dropped options in
exportToDocx: (#4997)pageSize— the html-to-docx engine accepts a page size, butexportToDocxonly forwardedmarginsandorientation, so the document was always the default (US Letter). You can now pass e.g.pageSize: { width: 11906, height: 16838 }to export A4.fontFamily— it was only applied to the serialized HTML (and only when anEditorStaticComponentwas provided), so the document default font was never set and Word fell back to Times New Roman. It now also sets the document default font (documentOptions.font).
@platejs/dnd
Bug Fixes
- Clear stale DnD drop indicators when dragging from a block into editor whitespace. (#5002)
@platejs/ai
Bug Fixes
- Updated
@platejs/table.
@platejs/table
Bug Fixes
- Remove the table when deleting its final column. (#4994)
@platejs/docx-io
Bug Fixes
- Fix
exportToDocxadding blank paragraphs at the top of the document.wrapHtmlForDocxemitted a<!DOCTYPE html>and indented the template; html-to-docx (html-to-vdom) keeps the DOCTYPE and the whitespace-only text nodes between tags and renders each as a blank paragraph. The wrapper now emits tight markup with no DOCTYPE. (#4991)
@platejs/ai
Bug Fixes
- Updated
@platejs/table.
@platejs/core
Bug Fixes
-
Add
transformInitialValueandnodeId.initialValueIdswhile keepingnormalizeInitialValueas a deprecated alias (#4987) -
Improve large-document mount and render performance across core element, mark, and
nodeIdpaths (#4987)- Cut
10kmixed-document core mount time from1240.60 msto468.26 mswithoutnodeId(62.3%,2.65xfaster) - Cut
10kmixed-document core mount time from1290.66 msto477.73 mswithnodeId(63.0%,2.70xfaster) - Cut mixed-document
nodeIdoverhead over core from+50.06 msto+9.46 ms(81.1%smaller) - Cut duplicate-id paste cost from
20.06 msto13.79 ms(31.2%,1.45xfaster) - Cut
10kcode-only mount time from1500.30 msto496.47 ms(66.9%,3.02xfaster) and shrink the code-only tax over core from+280.75 msto+27.89 ms(90.1%smaller) - Bring the current
10kcore and basic large-document mount lanes to Slate parity or better (core -3.5%,core + nodeId -1.6%,basic -1.2%) - Preserve Slate children for void
render.astags and Slate attributes on simple leaf/text render paths
- Cut
platejs
Bug Fixes
- Updated
@platejs/core,@platejs/slate,@platejs/utils.
@platejs/slate
Bug Fixes
-
Add experimental
editor.tf.setNodesBatchfor exact-path node prop updates on large documents (#4987)- Cut the large-document
set_nodehot path from18.56 msto2.63 msat1kblocks (7.05xfaster) - Cut the same path from
118.54 msto4.92 msat5kblocks (24.10xfaster) - Let
@platejs/corebatch livenodeIdnormalization instead of paying onesetNodescall per missing id - Keep
editor.tf.setNodesBatchexplicitly temporary. It is experimental and will be removed in a future release
- Cut the large-document
-
Updated
slate-hyperscript. (231b986)
@platejs/table
Bug Fixes
- Speed up unmerged table range selection while preserving merged-cell handling (#4987)
@platejs/utils
Bug Fixes
- Updated
@platejs/core,@platejs/slate.
@platejs/core
Bug Fixes
-
Fix
.configure({ inputRules })losing rules on subsequent editor instances (#4983)The user's config object was shared across resolutions via closure; clearing
inputRuleson the first resolve left later editors (StrictMode remounts, HMR, multi-editor pages) with no configured rules. -
Fix
createTextSubstitutionInputRulenot firing on the final character of flat matches (e.g.->→→,(c)→©) (#4983)
platejs
Bug Fixes
- Updated
@platejs/core,@platejs/utils.
@platejs/utils
Bug Fixes
- Updated
@platejs/core.
platejs
Bug Fixes
- Updated
@platejs/core,@platejs/slate,@platejs/utils.
@platejs/slate
Bug Fixes
- Updated
slate-react. (ce9ec87)
@platejs/utils
Bug Fixes
- Updated
@platejs/core,@platejs/slate.
@platejs/ai
Bug Fixes
- Updated
@platejs/markdown.
@platejs/markdown
Bug Fixes
- Respect
resourceLinkwhen serializing bare autolink literals (#4972)
CHANGELOG · v53.0.3...v53.0.4 · By @ajmnz
@platejs/ai
Bug Fixes
- Clear block streaming state when
aiChat.stop()stops generation (#4945)
@platejs/link
Bug Fixes
- Fix empty link normalization when suggestion acceptance removes the last link character (#4945)
platejs
Bug Fixes
- Updated
@platejs/utils.
@platejs/suggestion
Bug Fixes
- Fix inline-void delete and replace suggestions around mentions and paragraph boundaries (#4945)
@platejs/utils
Bug Fixes
- Add a trailing-block insert hook for normalization-driven insert behavior (#4945)
@platejs/list
Bug Fixes
- Fix
normalizeListStartto skip unordered list items and resume ordered list numbering past same-indent unordered siblings (#4954)
CHANGELOG · v53.0.1...v53.0.2 · By @dylans
@platejs/media
Bug Fixes
- Fix video URL parsing to avoid ReDoS on crafted time parameters (#4957)
CHANGELOG · v53.0.0...v53.0.1 · By @zbeyens
@platejs/autoformat
Breaking Changes
-
Deprecate
@platejs/autoformat. Markdown shortcuts and text substitutions are now authored asinputRuleson each feature plugin, andAutoformatPluginremains only as an inert compatibility export. (#4941)Migration:
- Remove
AutoformatPluginfrom your plugins and replace@platejs/autoformatafter migrating rules. - Replace each old
AutoformatRulewith the matching rule factory on the plugin that owns the feature. See the table below. - Replace symbol substitutions (arrows, fractions, smart quotes, legal, math operators) with
createTextSubstitutionInputRuleregistered on a localcreateSlatePlugin. - Replace
rules[].querywithenabledon the rule factory call. Replace the global code-block guard with a per-pluginenabledcheck. - Drop
enableUndoOnDelete— undo-on-delete is the built-in behavior. - Replace custom
AutoformatRuledefinitions withcreateRuleFactoryfromplatejs.
// Before import { AutoformatPlugin } from "@platejs/autoformat"; const editor = createPlateEditor({ plugins: [ AutoformatPlugin.configure({ options: { enableUndoOnDelete: true, rules: [ { match: "# ", mode: "block", type: KEYS.h1 }, { match: "**", mode: "mark", type: KEYS.bold }, { match: "* ", mode: "block", type: "list", format: (editor) => toggleList(editor, { listStyleType: KEYS.ul }), }, ], }, }), ], }); // After import { BoldRules } from "@platejs/basic-nodes"; import { BoldPlugin } from "@platejs/basic-nodes/react"; import { HeadingRules } from "@platejs/basic-nodes"; import { H1Plugin } from "@platejs/basic-nodes/react"; import { BulletedListRules } from "@platejs/list"; import { ListPlugin } from "@platejs/list/react"; const editor = createPlateEditor({ plugins: [ H1Plugin.configure({ inputRules: [HeadingRules.markdown()] }), BoldPlugin.configure({ inputRules: [BoldRules.markdown({ variant: "*" })], }), ListPlugin.configure({ inputRules: [BulletedListRules.markdown({ variant: "-" })], }), ], });Rule Map
Basic blocks —
@platejs/basic-nodesOld rule New rule { match: '# '..'###### ', mode: 'block', type: KEYS.h1..h6 }HxPlugin.configure({ inputRules: [HeadingRules.markdown()] })— register on eachH1Plugin..H6Plugin{ match: '> ', mode: 'block', type: KEYS.blockquote }BlockquotePlugin.configure({ inputRules: [BlockquoteRules.markdown()] }){ match: ['---', '—-', '___ '], mode: 'block', type: KEYS.hr }HorizontalRulePlugin.configure({ inputRules: [HorizontalRuleRules.markdown({ variant: '-' }), HorizontalRuleRules.markdown({ variant: '_' })] })Basic marks —
@platejs/basic-nodesOld rule New rule Owning plugin { match: '**', mode: 'mark', type: KEYS.bold }BoldRules.markdown({ variant: '*' })BoldPlugin{ match: '__', mode: 'mark', type: KEYS.underline }UnderlineRules.markdown()UnderlinePlugin{ match: '*', mode: 'mark', type: KEYS.italic }ItalicRules.markdown({ variant: '*' })ItalicPlugin{ match: '_', mode: 'mark', type: KEYS.italic }ItalicRules.markdown({ variant: '_' })ItalicPlugin{ match: '`', mode: 'mark', type: KEYS.code }CodeRules.markdown()CodePlugin{ match: '~~', mode: 'mark', type: KEYS.strikethrough }StrikethroughRules.markdown()StrikethroughPlugin{ match: '~', mode: 'mark', type: KEYS.sub }SubscriptRules.markdown()SubscriptPlugin{ match: '^', mode: 'mark', type: KEYS.sup }SuperscriptRules.markdown()SuperscriptPlugin{ match: '==', mode: 'mark', type: KEYS.highlight }HighlightRules.markdown({ variant: '==' })HighlightPlugin{ match: '≡', mode: 'mark', type: KEYS.highlight }HighlightRules.markdown({ variant: '≡' })HighlightPlugin{ match: '***', mode: 'mark', type: [bold, italic] }MarkComboRules.markdown({ variant: 'boldItalic' })BoldPlugin{ match: '__*', mode: 'mark', type: [underline, italic] }MarkComboRules.markdown({ variant: 'italicUnderline' })BoldPlugin{ match: '__**', mode: 'mark', type: [underline, bold] }MarkComboRules.markdown({ variant: 'boldUnderline' })BoldPlugin{ match: '___***', mode: 'mark', type: [underline, bold, italic] }MarkComboRules.markdown({ variant: 'boldItalicUnderline' })BoldPluginRegister each family on its owning plugin:
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" }), ], });Code block —
@platejs/code-blockOld rule New rule { match: '```', mode: 'block', type: KEYS.codeBlock, format: insertEmptyCodeBlock }CodeBlockPlugin.configure({ inputRules: [CodeBlockRules.markdown({ on: 'match' })] })Lists —
@platejs/listand@platejs/list-classicOld rule New rule { match: ['- ', '* '], mode: 'block', format: toggleList(..., { listStyleType: KEYS.ul }) }BulletedListRules.markdown({ variant: '-' }),BulletedListRules.markdown({ variant: '*' }){ match: /^\d+\.$ |^\d+\)$ /, matchByRegex: true, format: toggleList(..., { listStyleType: KEYS.ol }) }OrderedListRules.markdown({ variant: '.' }),OrderedListRules.markdown({ variant: ')' }){ match: '[] ', mode: 'block', format: toggleList(..., { listStyleType: KEYS.listTodo }) }TaskListRules.markdown({ checked: false }){ match: '[x] ', mode: 'block', format: toggleList + setNodes({ checked: true }) }TaskListRules.markdown({ checked: true })ListPlugin.configure({ inputRules: [ BulletedListRules.markdown({ variant: "-" }), BulletedListRules.markdown({ variant: "*" }), OrderedListRules.markdown({ variant: "." }), OrderedListRules.markdown({ variant: ")" }), TaskListRules.markdown({ checked: false }), TaskListRules.markdown({ checked: true }), ], });Replace
@platejs/listwith@platejs/list-classicimports when using the classic list model. The factory names are identical.Math —
@platejs/mathOld rule New rule Inline equation $…$InlineEquationPlugin.configure({ inputRules: [MathRules.markdown({ variant: '$' })] })Block equation $$…$$EquationPlugin.configure({ inputRules: [MathRules.markdown({ on: 'break', variant: '$$' })] })Link —
@platejs/linkOld behavior New rule [text](url)markdownLinkRules.markdown()Autolink on paste LinkRules.autolink({ variant: 'paste' })Autolink on space LinkRules.autolink({ variant: 'space' })Autolink on Enter LinkRules.autolink({ variant: 'break' })LinkPlugin.configure({ inputRules: [ LinkRules.markdown(), LinkRules.autolink({ variant: "paste" }), LinkRules.autolink({ variant: "space" }), LinkRules.autolink({ variant: "break" }), ], });Text substitutions (arrows, fractions, legal, math operators, smart quotes)
Move these to a local
createSlatePluginwithcreateTextSubstitutionInputRule:import { createSlatePlugin, createTextSubstitutionInputRule, KEYS, } from "platejs"; const isTextSubstitutionBlocked = (editor) => editor.api.some({ match: { type: [editor.getType(KEYS.codeBlock)] } }); const ShortcutsPlugin = createSlatePlugin({ key: "shortcuts", inputRules: [ createTextSubstitutionInputRule({ enabled: ({ editor }) => !isTextSubstitutionBlocked(editor), patterns: [ { format: "→", match: "->" }, { format: "⇒", match: "=>" }, { format: "½", match: "1/2" }, { format: "™", match: ["(tm)", "(TM)"] }, { format: ["“", "”"], match: '"' }, ], }), ], });Each pattern set is just data —
autoformatArrow,autoformatLegal,autoformatMath,autoformatPunctuation,autoformatSmartQuotes, andautoformatLegalHtmlfrom the old package map 1:1 ontopatternsarrays.AutoformatKitin the Plate registry is pre-built with all of them.Custom rules
Old
AutoformatRuleobjects have no direct replacement. Build a rule family withcreateRuleFactory:import { createRuleFactory } from "platejs"; const MyRules = { markdown: createRuleFactory({ type: "blockMatch", match: "!! ", format: "my-block", }), }; MyPlugin.configure({ inputRules: [MyRules.markdown()] });Option removals
enableUndoOnDelete— removed. Backspace on a rule-inserted node restores the source text by default.rules[].query— replaced byenabledon the rule factory call.rules[].preFormat/rules[].format— replaced by rule-familyformatandresolvecallbacks insidecreateRuleFactory.rules[].trigger— rule families set their own trigger. Override it with thetriggeroption on a customcreateRuleFactorycall.
See the Autoformat doc for the kit path and the Plugin Input Rules guide for the full runtime.
- Remove
@platejs/basic-nodes
Breaking Changes
-
Store blockquotes as container blocks with block children. Lift every selected nested quoted block one level on
Shift+Tab. Reset headings to paragraphs onBackspaceat block start before any merge. (#4941)Migration:
- Update persisted values, fixtures, and tests to use block children instead of direct text children.
- Expect
editor.tf.blockquote.toggle()to wrap or unwrap blocks instead of retagging one text block in place. - Empty later quoted paragraphs delete in place on
Backspaceinstead of jumping out of the quote. Backspaceat the start of a heading now resets the heading to a paragraph before any merge.- Legacy flat blockquote values still normalize on load, but persisted snapshots and fixtures should move to the new shape.
// Before { type: 'blockquote', children: [{ text: 'Quote' }] } // After { type: 'blockquote', children: [{ type: 'p', children: [{ text: 'Quote' }] }], }
@platejs/code-block
Breaking Changes
- Keep
Backspaceat the start of a non-empty first code line inside the code block. Merge an empty inner code line into the previous code line instead of unwrapping the block. (#4941)
@platejs/markdown
Breaking Changes
-
Round-trip blockquotes as nested block content instead of flat newline-packed text. Serialize image titles from
node.titleinstead of copying the caption into the markdown title slot. Preserve MDX media attribute expressions during markdown serialization instead of stringifying them into JSON text. Serialize plain URL links back to bare URL markdown instead of bracket-link form. Round-trip footnote references and definitions as dedicated footnote nodes instead of collapsing them to plain-text fallback. (#4941)Migration:
- Update snapshots and direct value assertions to expect
blockquote.childrento contain block nodes such as paragraphs and lists. - If you generate initial editor values from markdown, hydrate blockquotes with paragraph children instead of flat text.
- If you want markdown output like
, setnode.title. Images without a title now serialize as. - If you serialize MDX media nodes with expression attributes like
width={640}, expect those expressions to stay as expressions instead of turning into quoted JSON. - Plain URL links such as
https://platejs.orgnow serialize as bare URLs instead of[https://platejs.org](https://platejs.org). - If you enable footnote-aware markdown input, install
@platejs/footnoteand includeBaseFootnoteReferencePluginandBaseFootnoteDefinitionPluginso footnote nodes have real editor semantics instead of falling back to unknown node types.
// Before { type: 'blockquote', children: [{ text: 'Quote\\nNext line' }] } // After { type: 'blockquote', children: [ { type: 'p', children: [{ text: 'Quote' }] }, { type: 'p', children: [{ text: 'Next line' }] }, ], } - Update snapshots and direct value assertions to expect
Bug Fixes
-
Write canonical date nodes as
<date value="..."/>and round-trip normalized media embed metadata (#4941) -
Preserve unknown MDX and raw HTML block source more faithfully during markdown deserialization fallback (#4941)
@platejs/table
Breaking Changes
- Escalate the second
selectAllfrom the current table to the whole document. (#4941)
@platejs/core
Features
- Add
liftas a break and delete rule action for blocks that should leave one ancestor level instead of resetting or exiting. Reset the trailing block to a paragraph whensplitResethandles selected heading text. (#4941)
Bug Fixes
-
Add
createRuleFactoryfor building input rule families with overridable defaults and required options (#4941) -
Add
useNavigationHighlight(path)for React node components that need the current navigation-feedback target without reading plugin options directly (#4941)
@platejs/footnote
Features
- Add
FootnoteReferencePlugin,FootnoteDefinitionPlugin, andFootnoteInputPluginfor real footnote nodes and inline[^combobox insertion in Plate editors. (#4941)
@platejs/date
Bug Fixes
- Store date nodes as canonical
YYYY-MM-DDvalues and preserve unparseable legacy text as fallback data (#4941)
@platejs/link
Bug Fixes
- Keep pasted URLs literal inside markdown link source entry by default (#4941)
@platejs/list
Bug Fixes
- Allow list markdown rule families to override shared runtime rule fields while keeping semantic
variantandcheckedoptions (#4941)
@platejs/list-classic
Bug Fixes
- Allow classic list markdown rule families to override shared runtime rule fields while keeping semantic
variantandcheckedoptions (#4941)
@platejs/media
Bug Fixes
-
Support allowlisted Twitter/X embed snippet extraction in media embed URL transforms (#4941)
-
Normalize supported media embeds into canonical provider metadata and preserve source URLs for embed editing (#4941)
@platejs/slate
Bug Fixes
- Updated
slate,slate-dom. (081cbe9)
@platejs/toc
Bug Fixes
-
Add active section state to
useTocElementStateso TOC elements can mark the current heading while the document scrolls (#4941) -
Fix TOC activation to navigate without entering block-selection mode (#4941)
@platejs/utils
Bug Fixes
- Add
KEYS.footnoteDefinition,KEYS.footnoteReference, andKEYS.footnoteInput(#4941)
CHANGELOG · v52.3.22...v53.0.0 · By @zbeyens, @github-actions[bot]