This page only covers major breaking changes. For patch and minor changes, refer to the individual package CHANGELOG.md
files or visit the GitHub Releases page.
This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.
49.0.0
[email protected]
- #4327 by @zbeyens –
- Renamed package to
platejs
:- Replace all
@udecode/plate/react
withplatejs/react
- Replace all
'@udecode/plate'
with'platejs'
- Replace all
- Renamed package to
@platejs/[email protected]
-
- Renamed all
@udecode/plate-*
packages to@platejs/*
. Replace@udecode/plate-
with@platejs/
in your code.
- Renamed all
-
-
Replaced
editor.api.shouldMergeNodesRemovePrevNode
witheditor.api.shouldMergeNodes
.shouldMergeNodes
is now controlling the remove + merge behavior- Returns
true
if the default merging behavior should be applied. - Returns
false
if the default merging behavior should not be applied. This is used by Plate to prevent void blocks deletion, and to prioritize empty block deletion over merging.
// Before editor.api.shouldMergeNodesRemovePrevNode(prev, current); // After editor.api.shouldMergeNodes(prev, current);
- Returns
-
Replace
editor.api.fragment
optionstructuralTypes
withunwrap
.// Before editor.api.fragment(editor.selection, { structuralTypes: ['table'] }); // After editor.api.fragment(editor.selection, { unwrap: ['table'] });
-
Minor Changes
@platejs/[email protected]
-
editor.getType()
now takes apluginKey: string
instead of aplugin: PlatePlugin
instance.- Example: Use
editor.getType(ParagraphPlugin.key)
instead ofeditor.getType(ParagraphPlugin)
.
- Example: Use
- Plugins without a
key
property will not be registered into the editor. - Passing
disabled: true
prop toPlateContent
will now also set the editor toreadOnly: true
state internally. - Editor DOM state properties have been moved under
editor.dom
namespace:editor.currentKeyboardEvent
is noweditor.dom.currentKeyboardEvent
.editor.prevSelection
is noweditor.dom.prevSelection
.
- Editor metadata properties have been moved under
editor.meta
namespace:editor.isFallback
is noweditor.meta.isFallback
editor.key
is noweditor.meta.key
editor.pluginList
is noweditor.meta.pluginList
editor.shortcuts
is noweditor.meta.shortcuts
editor.uid
is noweditor.meta.uid
NodeIdPlugin
is now enabled by default as part of the core plugins. This automatically assigns unique IDs to block nodes.- Migration: If you were not previously using
NodeIdPlugin
and wish to maintain the old behavior (no automatic IDs), explicitly disable it in your editor configuration:const editor = usePlateEditor({ // ...other options nodeId: false, // Disables automatic node ID generation });
- Migration: If you were not previously using
- The
components
prop has been removed fromserializeHtml
andPlateStatic
.- Migration: Pass the
components
tocreateSlateEditor({ components })
or the individual plugins instead.
- Migration: Pass the
- Plugin Shortcuts System Changes:
- Shortcut keys defined in
editor.shortcuts
are now namespaced by the plugin key (e.g.,code.toggle
forCodePlugin
). - The
priority
property for shortcuts is used to resolve conflicts when multiple shortcuts share the exact same key combination, not for overriding shortcuts by name. preventDefault
for plugin shortcuts now defaults totrue
, unless the handler returnsfalse
(i.e. not handled). This means browser default actions for these key combinations will be prevented unless explicitly allowed.- Migration: If you need to allow browser default behavior for a specific shortcut, set
preventDefault: false
in its configuration:MyPlugin.configure({ shortcuts: { myAction: { keys: 'mod+s', preventDefault: false, // Example: Allow browser's default save dialog }, }, });
- Migration: If you need to allow browser default behavior for a specific shortcut, set
- Shortcut keys defined in
-
- Renamed all
@udecode/plate-*
packages to@platejs/*
. Replace@udecode/plate-
with@platejs/
in your code.
- Renamed all
Minor Changes
- #4327 by @zbeyens –
- New editor DOM state fields available under
editor.dom
:editor.dom.composing
: Boolean, true if the editor is currently composing text (e.g., during IME input).editor.dom.focused
: Boolean, true if the editor currently has focus.editor.dom.readOnly
: Boolean, true if the editor is in read-only mode. Passing thereadOnly
prop toPlateContent
will sync its value to this state and to theuseEditorReadOnly
hook.
- New editor metadata fields:
editor.meta.components
- stores the plugin components by key
- New hook
useEditorComposing
: Allows subscription to the editor's composing state (editor.dom.composing
) outside ofPlateContent
. createPlateEditor
andusePlateEditor
now accept areadOnly
option to initialize the editor in a read-only state. For dynamic read-only changes after initialization, continue to use thereadOnly
prop on the<Plate>
or<PlateContent>
component.- New plugin field:
editOnly
(boolean or object).- When
true
or when specific properties are true in the object, Plate will disable certain plugin behaviors (handlers, rendering, injections) in read-only mode and re-enable them if the editor becomes editable. - By default,
render
,handlers
, andinject
are considered edit-only (true
).normalizeInitialValue
defaults to always active (false
). - Example:
editOnly: { render: false, normalizeInitialValue: true }
would make rendering active always, but normalization only in edit mode.
- When
- New plugin field:
render.as
(keyof HTMLElementTagNameMap
).- Specifies the default HTML tag name to be used by
PlateElement
(default:'div'
) orPlateLeaf
(default:'span'
) when rendering the node, but only if no customnode.component
is provided for the plugin. - Example:
render: { as: 'h1' }
would make the plugin render its node as an<h1>
tag by default without the need to provide a custom component.
- Specifies the default HTML tag name to be used by
- New plugin field:
node.isContainer
(boolean).- When
true
, indicates that the plugin's elements are primarily containers for other content.
- When
- New plugin field:
node.isStrictSiblings
(boolean).- When
true
, indicates that the element enforces strict sibling type constraints and only allows specific siblings (e.g.,td
can only havetd
siblings,column
can only havecolumn
siblings). - Used by
editor.tf.insertExitBreak
functionality to determine appropriate exit points in nested structures.
- When
- New plugin field:
rules
(object).- Configures common editing behaviors declaratively instead of overriding editor methods. See documentation for more details.
rules.break
: Controls Enter key behavior (empty
,default
,emptyLineEnd
,splitReset
)rules.delete
: Controls Backspace key behavior (start
,empty
)rules.merge
: Controls block merging behavior (removeEmpty
)rules.normalize
: Controls normalization behavior (removeEmpty
)rules.selection
: Controls cursor positioning behavior (affinity
)rules.match
: Conditional rule application based on node properties
- Plugin shortcuts can now automatically leverage existing plugin transforms by specifying the transform name, in addition to custom handlers.
- New editor transform methods for keyboard handling:
editor.tf.escape
: Handle Escape key events. Returnstrue
if the event is handled.editor.tf.moveLine
: Handle ArrowDown and ArrowUp key events withreverse
option for direction. Returnstrue
if the event is handled.editor.tf.selectAll
: Handle Ctrl/Cmd+A key events for selecting all content. Returnstrue
if the event is handled.editor.tf.tab
: Handle Tab and Shift+Tab key events withreverse
option for Shift+Tab. Returnstrue
if the event is handled.
- New editor DOM state fields available under
@platejs/[email protected]
-
- Renamed all
@udecode/plate-*
packages to@platejs/*
. Replace@udecode/plate-
with@platejs/
in your code.
- Renamed all
-
-
Node type definitions (e.g.,
TImageElement
,TParagraphElement
) previously co-located with their respective plugin packages (like@udecode/plate-media
) have been centralized into@platejs/utils
. These are typically re-exported via the mainplatejs
package.-
Migration: Update imports for these types to pull from
platejs
.// Before // import { TImageElement } from '@udecode/plate-media'; // After import { TImageElement } from 'platejs';
-
-
Removed
structuralTypes
option fromuseSelectionFragment
anduseSelectionFragmentProp
. These hooks now automatically useplugin.node.isContainer
from enabled plugins. -
Removed:
createNodesHOC
createNodesWithHOC
createNodeHOC
-
Removed
usePlaceholderState
hook.- Migration: Use the
BlockPlaceholderPlugin
(typically fromplatejs
) instead of thewithPlaceholders
HOC andusePlaceholderState
. Configure placeholders directly within theBlockPlaceholderPlugin
options.// Example BlockPlaceholderPlugin configuration BlockPlaceholderPlugin.configure({ options: { className: 'before:absolute before:cursor-text before:opacity-30 before:content-[attr(placeholder)]', placeholders: { [ParagraphPlugin.key]: 'Type something...', // ...other placeholders }, query: ({ editor, path }) => { // Example query: only show for top-level empty blocks return ( path.length === 1 && editor.api.isEmpty(editor.children[path[0]]) ); }, }, });
- Migration: Use the
-
@platejs/[email protected]
-
- Copilot API method changes:
editor.api.copilot.accept
is noweditor.tf.copilot.accept
.editor.api.copilot.acceptNextWord
is noweditor.tf.copilot.acceptNextWord
.editor.api.copilot.reset
is noweditor.api.copilot.reject
.
- Removed Default Shortcuts for Copilot:
- Only
accept
(Tab) andreject
(Escape) shortcuts are included by default forCopilotPlugin
. acceptNextWord
andtriggerSuggestion
shortcuts must now be configured manually using theshortcuts
field when configuring the plugin.- Example:
CopilotPlugin.configure({ // ... other options shortcuts: { acceptNextWord: { keys: 'mod+right', }, triggerSuggestion: { keys: 'ctrl+space', }, }, });
- Only
- Copilot API method changes:
-
- Renamed all
@udecode/plate-*
packages to@platejs/*
. Replace@udecode/plate-
with@platejs/
in your code.
- Renamed all
@platejs/[email protected]
-
-
Package
@udecode/plate-alignment
has been deprecated. -
TextAlignPlugin
(formerlyAlignPlugin
) has been moved to the@platejs/basic-styles
package. -
Migration:
- Remove
@udecode/plate-alignment
from your dependencies. - Add
@platejs/basic-styles
to your dependencies if not already present. - Import
TextAlignPlugin
from@platejs/basic-styles/react
.
- Remove
-
Renamed
AlignPlugin
toTextAlignPlugin
and changed plugin key from'align'
to'textAlign'
.// Before import { AlignPlugin } from '@udecode/plate-alignment/react'; // After import { TextAlignPlugin } from '@platejs/basic-styles/react';
-
setAlign
signature change:
// Before setAlign(editor, { value: 'center', setNodesOptions }); // After setAlign(editor, 'center', setNodesOptions);
- Removed
useAlignDropdownMenu
anduseAlignDropdownMenuState
. Use it in your own codebase, for example:
export function AlignToolbarButton() { const editor = useEditorRef(); const value = useSelectionFragmentProp({ defaultValue: 'start', structuralTypes, getProp: (node) => node.align, }); const onValueChange = (newValue: string) => { editor.tf.textAlign.setNodes(newValue as Alignment); editor.tf.focus(); }; // ... }
-
@platejs/[email protected]
-
- Replaced
BaseAutoformatPlugin
withAutoformatPlugin
, which is no longer a React plugin. Migration: Replace@udecode/plate-autoformat/react
import with@udecode/plate-autoformat
.
- Replaced
-
- The following plugins now default to
editOnly: true
. This means their core functionalities (handlers, rendering injections, etc.) will be disabled when the editor is in read-only mode. To override this behavior for a specific plugin, configure itseditOnly
field. For example,SomePlugin.configure({ editOnly: false })
.
- The following plugins now default to
-
- Renamed all
@udecode/plate-*
packages to@platejs/*
. Replace@udecode/plate-
with@platejs/
in your code.
- Renamed all
@platejs/[email protected]
- #4327 by @zbeyens –
- Package
@udecode/plate-basic-elements
has been deprecated. BasicElementsPlugin
has been renamed toBasicBlocksPlugin
.- Its plugins have been moved to the new
@platejs/basic-nodes
package. - Migration:
- Replace
@udecode/plate-basic-elements
with@platejs/basic-nodes
in your dependencies. - Update import paths from
@udecode/plate-basic-elements/react
to@platejs/basic-nodes/react
. - For detailed changes to individual plugins, default HTML tags, and shortcut configurations, refer to the changeset for
@platejs/basic-nodes
.
- Replace
- Package
@platejs/[email protected]
- #4327 by @zbeyens –
- Package
@udecode/plate-basic-marks
has been deprecated. - Its plugins have been moved to the new
@platejs/basic-nodes
package. - Migration:
- Replace
@udecode/plate-basic-marks
with@platejs/basic-nodes
in your dependencies. - Update import paths from
@udecode/plate-basic-marks/react
to@platejs/basic-nodes/react
. - For detailed changes to individual plugins, default HTML tags, and shortcut configurations, refer to the changeset for
@platejs/basic-nodes
.
- Replace
- Package
@platejs/[email protected]
- #4327 by @zbeyens –
- The packages
@udecode/plate-basic-elements
and@udecode/plate-basic-marks
have been deprecated. All their plugins are now consolidated into the new@platejs/basic-nodes
package. - Migration:
- Replace
@udecode/plate-basic-elements
and@udecode/plate-basic-marks
in your dependencies with@platejs/basic-nodes
. - Update all import paths from
@udecode/plate-basic-elements/react
or@udecode/plate-basic-marks/react
to@platejs/basic-nodes/react
. CodeBlockPlugin
is not part of@platejs/basic-nodes
. Ensure it is imported from@platejs/code-block/react
.
- Replace
SkipMarkPlugin
(standalone) is removed. Its functionality is now built into the core editor. To enable boundary clearing for a specific mark, configure the mark plugin directly:plugin.configure({ rules: { selection: { affinity: 'outward' } } })
.- Default HTML Tag Changes:
- Blocks: Element plugins in
@udecode/plate-basic-nodes
(e.g.,BlockquotePlugin
,HeadingPlugin
,HorizontalRulePlugin
) now default to rendering with specific HTML tags (<blockquote>
,<h1>-<h6>
,<hr>
respectively).ParagraphPlugin
still defaults to<div>
. If you relied on previous defaults or need different tags, provide a custom component or use therender.as
option. - Marks: Mark plugins in
@udecode/plate-basic-nodes
(e.g.,BoldPlugin
,CodePlugin
,ItalicPlugin
) now default to specific HTML tags (<strong>
,<code>
,<em>
respectively). If you relied on previous defaults or need different tags, provide a custom component or use therender.as
option.
- Blocks: Element plugins in
- Removed Default Shortcuts:
- Default keyboard shortcuts are no longer bundled with most plugins (exceptions: bold, italic, underline).
- Configure shortcuts manually via the
shortcuts
field in plugin configuration. - Example (Block Plugins):
H1Plugin.configure({ shortcuts: { toggle: { keys: 'mod+alt+1' } } }); BlockquotePlugin.configure({ shortcuts: { toggle: { keys: 'mod+shift+period' } }, });
- Example (Mark Plugins):
CodePlugin.configure({ shortcuts: { toggle: { keys: 'mod+e' } } }); StrikethroughPlugin.configure({ shortcuts: { toggle: { keys: 'mod+shift+x' } }, }); SubscriptPlugin.configure({ shortcuts: { toggle: { keys: 'mod+comma' } }, }); SuperscriptPlugin.configure({ shortcuts: { toggle: { keys: 'mod+period' } }, }); HighlightPlugin.configure({ shortcuts: { toggle: { keys: 'mod+shift+h' } }, });
- The packages
@platejs/[email protected]
- #4327 by @zbeyens –
- Package
@udecode/plate-block-quote
has been deprecated. BlockquotePlugin
has been moved to the@platejs/basic-nodes
package.- Migration:
- Remove
@udecode/plate-block-quote
from your dependencies. - Add
@platejs/basic-nodes
to your dependencies if not already present. - Import
BlockquotePlugin
from@platejs/basic-nodes/react
.
- Remove
- Package
@platejs/[email protected]
-
-
Package
@udecode/plate-break
has been deprecated. -
SoftBreakPlugin
has been removed. Migration:- For
shift+enter
rules: no migration is needed - this behavior is built into Plate by default. - For
enter
rules: useplugin.configure({ rules: { break: { default: 'lineBreak' } } })
to insert a line break instead of a hard break onEnter
keydown when the selection is within the configured node type. - For more complex break rules: use
overrideEditor
to override theinsertBreak
transform with custom logic.
- For
-
ExitBreakPlugin
has been moved to@platejs/utils
(which is re-exported viaplatejs
) with a simplified API and improved behavior.-
Behavior Change: Instead of always exiting to the root level of the document, exiting will now insert a block to the nearest exitable ancestor that has
isStrictSiblings: false
. This means deeply nested structures (like tables in columns) are exitable at many levels. -
Migration:
-
Remove
@udecode/plate-break
from your dependencies. -
Replace
@udecode/plate-break
import withplatejs
. -
Important: If not using Plate plugins, you must set
isStrictSiblings: true
on your custom node plugins that can't have paragraph siblings for exit break to work correctly. -
Replace complex rule-based configuration with simple shortcuts:
// Before (old API) ExitBreakPlugin.configure({ options: { rules: [ { hotkey: 'mod+enter' }, { hotkey: 'mod+shift+enter', before: true }, ], }, }); // After (new API) ExitBreakPlugin.configure({ shortcuts: { insert: { keys: 'mod+enter' }, insertBefore: { keys: 'mod+shift+enter' }, }, });
-
-
-
@platejs/[email protected]
- #4327 by @zbeyens –
- Renamed all
@udecode/plate-*
packages to@platejs/*
. Replace@udecode/plate-
with@platejs/
in your code.
- Renamed all
@platejs/[email protected]
-
-
CaptionPlugin
optionoptions.plugins
(accepting an array ofPlatePlugin
) has been renamed tooptions.query.allow
(accepting an array of plugin keys). -
Migration:
// Before CaptionPlugin.configure({ options: { plugins: [ImagePlugin], // ImagePlugin is an example }, }); // After CaptionPlugin.configure({ options: { query: { allow: [ImagePlugin.key], // Use the plugin's key }, }, });
-
-
- Renamed all
@udecode/plate-*
packages to@platejs/*
. Replace@udecode/plate-
with@platejs/
in your code.
- Renamed all
@platejs/[email protected]
- #4327 by @zbeyens –
CodeBlockPlugin
now defaults to rendering the code block container with a<pre>
HTML tag if no custom component is provided forCodeBlockElement
(or the plugin keycode_block
).
@platejs/[email protected]
- #4327 by @zbeyens –
- Renamed all
@udecode/plate-*
packages to@platejs/*
. Replace@udecode/plate-
with@platejs/
in your code.
- Renamed all
@platejs/[email protected]
-
CommentsPlugin
has been renamed toCommentPlugin
.- Update imports and plugin configurations accordingly.
- Example:
CommentsPlugin.key
becomesCommentPlugin.key
.
- Example:
- Package name has been changed to
@platejs/comment
.
-
- Renamed all
@udecode/plate-*
packages to@platejs/*
. Replace@udecode/plate-
with@platejs/
in your code.
- Renamed all
@platejs/[email protected]
- #4327 by @zbeyens –
- Renamed all
@udecode/plate-*
packages to@platejs/*
. Replace@udecode/plate-
with@platejs/
in your code.
- Renamed all
@platejs/[email protected]
- #4327 by @zbeyens –
- Renamed all
@udecode/plate-*
packages to@platejs/*
. Replace@udecode/plate-
with@platejs/
in your code.
- Renamed all
@platejs/[email protected]
- #4327 by @zbeyens –
- Renamed all
@udecode/plate-*
packages to@platejs/*
. Replace@udecode/plate-
with@platejs/
in your code.
- Renamed all
@platejs/[email protected]
- #4327 by @zbeyens –
- Renamed all
@udecode/plate-*
packages to@platejs/*
. Replace@udecode/plate-
with@platejs/
in your code.
- Renamed all
@platejs/[email protected]
-
- The following plugins now default to
editOnly: true
. This means their core functionalities (handlers, rendering injections, etc.) will be disabled when the editor is in read-only mode. To override this behavior for a specific plugin, configure itseditOnly
field. For example,SomePlugin.configure({ editOnly: false })
.
- The following plugins now default to
-
- Renamed all
@udecode/plate-*
packages to@platejs/*
. Replace@udecode/plate-
with@platejs/
in your code.
- Renamed all
@platejs/[email protected]
-
- The following plugins now default to
editOnly: true
. This means their core functionalities (handlers, rendering injections, etc.) will be disabled when the editor is in read-only mode. To override this behavior for a specific plugin, configure itseditOnly
field. For example,SomePlugin.configure({ editOnly: false })
.
- The following plugins now default to
-
- Renamed all
@udecode/plate-*
packages to@platejs/*
. Replace@udecode/plate-
with@platejs/
in your code.
- Renamed all
@platejs/[email protected]
-
- The following plugins now default to
editOnly: true
. This means their core functionalities (handlers, rendering injections, etc.) will be disabled when the editor is in read-only mode. To override this behavior for a specific plugin, configure itseditOnly
field. For example,SomePlugin.configure({ editOnly: false })
.
- The following plugins now default to
-
- Renamed all
@udecode/plate-*
packages to@platejs/*
. Replace@udecode/plate-
with@platejs/
in your code.
- Renamed all
@platejs/[email protected]
- #4327 by @zbeyens –
- Renamed all
@udecode/plate-*
packages to@platejs/*
. Replace@udecode/plate-
with@platejs/
in your code.
- Renamed all
@platejs/[email protected]
- #4327 by @zbeyens –
- Renamed all
@udecode/plate-*
packages to@platejs/*
. Replace@udecode/plate-
with@platejs/
in your code.
- Renamed all
@platejs/[email protected]
- #4327 by @zbeyens –
- Renamed all
@udecode/plate-*
packages to@platejs/*
. Replace@udecode/plate-
with@platejs/
in your code.
- Renamed all
@platejs/[email protected]
-
- Removed
setBlockBackgroundColor
- Removed
setFontSize
– usetf.fontSize.addMark
instead:
// Before editor.api.fontSize.addMark('16px'); // After editor.tf.fontSize.addMark('16px');
- Removed
useColorInput
. Use it in your own codebase, for example:
function ColorInput() { const inputRef = React.useRef<HTMLInputElement | null>(null); const onClick = () => { inputRef.current?.click(); }; // ... }
- Removed
useColorsCustom
anduseColorsCustomState
. Use it in your own codebase, for example:
function ColorCustom({ color, colors, customColors, updateCustomColor }) { const [customColor, setCustomColor] = React.useState<string>(); const [value, setValue] = React.useState<string>(color || '#000000'); React.useEffect(() => { if ( !color || customColors.some((c) => c.value === color) || colors.some((c) => c.value === color) ) { return; } setCustomColor(color); }, [color, colors, customColors]); const computedColors = React.useMemo( () => customColor ? [ ...customColors, { isBrightColor: false, name: '', value: customColor, }, ] : customColors, [customColor, customColors] ); const updateCustomColorDebounced = React.useCallback( debounce(updateCustomColor, 100), [updateCustomColor] ); const inputProps = { value, onChange: (e: React.ChangeEvent<HTMLInputElement>) => { setValue(e.target.value); updateCustomColorDebounced(e.target.value); }, }; // ... }
- Removed
useColorDropdownMenu
anduseColorDropdownMenuState
. Use it in your own codebase, for example:
export function FontColorToolbarButton({ nodeType }) { const editor = useEditorRef(); const selectionDefined = useEditorSelector( (editor) => !!editor.selection, [] ); const color = useEditorSelector( (editor) => editor.api.mark(nodeType) as string, [nodeType] ); const [selectedColor, setSelectedColor] = React.useState<string>(); const [open, setOpen] = React.useState(false); const onToggle = React.useCallback( (value = !open) => { setOpen(value); }, [open, setOpen] ); const updateColor = React.useCallback( (value: string) => { if (editor.selection) { setSelectedColor(value); editor.tf.select(editor.selection); editor.tf.focus(); editor.tf.addMarks({ [nodeType]: value }); } }, [editor, nodeType] ); const clearColor = React.useCallback(() => { if (editor.selection) { editor.tf.select(editor.selection); editor.tf.focus(); if (selectedColor) { editor.tf.removeMarks(nodeType); } onToggle(); } }, [editor, selectedColor, onToggle, nodeType]); React.useEffect(() => { if (selectionDefined) { setSelectedColor(color); } }, [color, selectionDefined]); // ... }
- Removed
@platejs/[email protected]
- #4327 by @zbeyens –
- Package
@udecode/plate-heading
has been deprecated.HeadingPlugin
and individual heading plugins (e.g.,H1Plugin
) have been moved to@platejs/basic-nodes
.- Migration: Import from
@platejs/basic-nodes/react
(e.g.,import { HeadingPlugin } from '@platejs/basic-nodes/react';
).
- Migration: Import from
TocPlugin
has been moved to@platejs/toc
.- Migration: Add
@platejs/toc
to your dependencies and importTocPlugin
from@platejs/toc/react
.
- Migration: Add
- Remove
@udecode/plate-heading
from your dependencies. HEADING_LEVELS
has been removed. UseKEYS.heading
instead.
- Package
@platejs/[email protected]
- #4327 by @zbeyens –
- Package
@udecode/plate-highlight
has been deprecated. HighlightPlugin
has been moved to the@platejs/basic-nodes
package.- Migration:
- Remove
@udecode/plate-highlight
from your dependencies. - Add
@platejs/basic-nodes
to your dependencies if not already present. - Import
HighlightPlugin
from@platejs/basic-nodes/react
.
- Remove
- Package
@platejs/[email protected]
- #4327 by @zbeyens –
- Package
@udecode/plate-horizontal-rule
has been deprecated. HorizontalRulePlugin
has been moved to the@platejs/basic-nodes
package.- Migration:
- Remove
@udecode/plate-horizontal-rule
from your dependencies. - Add
@platejs/basic-nodes
to your dependencies if not already present. - Import
HorizontalRulePlugin
from@platejs/basic-nodes/react
.
- Remove
- Package
@platejs/[email protected]
- #4327 by @zbeyens –
- Renamed all
@udecode/plate-*
packages to@platejs/*
. Replace@udecode/plate-
with@platejs/
in your code.
- Renamed all
@platejs/[email protected]
- #4327 by @zbeyens –
- Package
@udecode/plate-indent-list
has been renamed to@platejs/list
. - Migration:
- Rename all import paths from
@udecode/plate-indent-list
to@platejs/list
. - Update your
package.json
: remove@udecode/plate-indent-list
and add@platejs/list
.
- Rename all import paths from
- Package
@platejs/[email protected]
- #4327 by @zbeyens –
- Renamed all
@udecode/plate-*
packages to@platejs/*
. Replace@udecode/plate-
with@platejs/
in your code.
- Renamed all
@platejs/[email protected]
- #4327 by @zbeyens –
- Package
@udecode/plate-kbd
has been deprecated. KbdPlugin
has been moved to the@platejs/basic-nodes
package.- Migration:
- Remove
@udecode/plate-kbd
from your dependencies. - Add
@platejs/basic-nodes
to your dependencies if not already present. - Import
KbdPlugin
from@platejs/basic-nodes/react
.
- Remove
- Package
@platejs/[email protected]
-
- Delete backward from a column start will merge into the previous column
-
- Renamed all
@udecode/plate-*
packages to@platejs/*
. Replace@udecode/plate-
with@platejs/
in your code.
- Renamed all
@platejs/[email protected]
-
-
Package
@udecode/plate-line-height
has been deprecated. -
LineHeightPlugin
has been moved to the@platejs/basic-styles
package. -
Migration:
- Remove
@udecode/plate-line-height
from your dependencies. - Add
@platejs/basic-styles
to your dependencies if not already present. - Import
LineHeightPlugin
from@platejs/basic-styles/react
.
- Remove
-
setLineHeight
signature change:
// Before setLineHeight(editor, { value: 1.5, setNodesOptions }); // After setLineHeight(editor, 1.5, setNodesOptions);
- Removed
useLineHeightDropdownMenu
anduseLineHeightDropdownMenuState
. Use it in your own codebase, for example:
export function LineHeightToolbarButton() { const editor = useEditorRef(); const { defaultNodeValue, validNodeValues: values = [] } = editor.getInjectProps(LineHeightPlugin); const value = useSelectionFragmentProp({ defaultValue: defaultNodeValue, getProp: (node) => node.lineHeight, }); const onValueChange = (newValue: string) => { editor.tf.lineHeight.setNodes(Number(newValue)); editor.tf.focus(); }; // ... }
-
@platejs/[email protected]
- #4327 by @zbeyens –
- Renamed all
@udecode/plate-*
packages to@platejs/*
. Replace@udecode/plate-
with@platejs/
in your code.
- Renamed all
@platejs/[email protected]
-
- The previous
@udecode/plate-list
(classic list implementation) has been moved to@platejs/list-classic
.- Migration for users of the classic list:
- Rename all import paths from
@udecode/plate-list
to@platejs/list-classic
. - Update your
package.json
: remove the old@udecode/plate-list
(if it was a direct dependency) and add@platejs/list-classic
.
- Rename all import paths from
- Migration for users of the classic list:
- This package,
@platejs/list
, now contains the functionality previously in@udecode/plate-indent-list
(indent-based list system).- Plugin names have been generalized:
IndentListPlugin
is nowListPlugin
,BaseIndentListPlugin
isBaseListPlugin
, etc. (*IndentList*
->*List*
). - The primary plugin key is now
list
(e.g.,ListPlugin.key
) instead oflistStyleType
. - Constants for list keys previously in
INDENT_LIST_KEYS
are now available underKEYS
fromplatejs
.- Migration for constants:
INDENT_LIST_KEYS.listStyleType
->KEYS.listType
INDENT_LIST_KEYS.todo
->KEYS.listTodo
INDENT_LIST_KEYS.checked
->KEYS.listChecked
- Other
INDENT_LIST_KEYS.*
map toKEYS.*
accordingly.
- Migration for constants:
- Removed
listStyleTypes
option fromListPlugin
. You should control list rendering viarender.belowNodes
instead. - Removed
renderListBelowNodes
.
- Plugin names have been generalized:
- For changelogs of the indent-based list system (now in this package) version
<=48
(when it was@udecode/plate-indent-list
), refer to its archived changelog.
- The previous
-
- Renamed all
@udecode/plate-*
packages to@platejs/*
. Replace@udecode/plate-
with@platejs/
in your code.
- Renamed all
@platejs/[email protected]
- #4327 by @zbeyens –
- Removed Default Shortcuts for
BulletedListPlugin
andNumberedListPlugin
.- These shortcuts must now be configured manually using the
shortcuts
field. - Example:
BulletedListPlugin.configure({ shortcuts: { toggle: { keys: 'mod+alt+5' } }, }); NumberedListPlugin.configure({ shortcuts: { toggle: { keys: 'mod+alt+6' } }, });
- These shortcuts must now be configured manually using the
- Package
@udecode/plate-list
has been moved to@platejs/list-classic
.- Migration:
- Rename all import paths from
@udecode/plate-list
to@platejs/list-classic
. - Update your
package.json
: remove@udecode/plate-list
and add@platejs/list-classic
.
- Rename all import paths from
- Migration:
- For changelogs of
@udecode/plate-list
version<=48
, refer to its archived changelog.
- Removed Default Shortcuts for
@platejs/[email protected]
-
- Function
indentListToMdastTree
has been renamed tolistToMdastTree
to align with the list plugin renames (IndentListPlugin
->ListPlugin
).
- Function
-
- Renamed all
@udecode/plate-*
packages to@platejs/*
. Replace@udecode/plate-
with@platejs/
in your code.
- Renamed all
@platejs/[email protected]
- #4327 by @zbeyens –
- Renamed all
@udecode/plate-*
packages to@platejs/*
. Replace@udecode/plate-
with@platejs/
in your code.
- Renamed all
@platejs/[email protected]
- #4327 by @zbeyens –
- Renamed all
@udecode/plate-*
packages to@platejs/*
. Replace@udecode/plate-
with@platejs/
in your code.
- Renamed all
@platejs/[email protected]
-
- The type
TMentionInputElement
has been removed. - Use
TComboboxInputElement
from@udecode/plate
instead for input elements, as mention functionality is built upon the combobox.
- The type
-
- Renamed all
@udecode/plate-*
packages to@platejs/*
. Replace@udecode/plate-
with@platejs/
in your code.
- Renamed all
@platejs/[email protected]
-
-
Package
@udecode/plate-node-id
has been deprecated. -
NodeIdPlugin
functionality is now part of@platejs/core
and is enabled by default. -
Migration:
-
Remove
NodeIdPlugin
from your explicit plugin list if it was added manually. -
Remove
@udecode/plate-node-id
from your dependencies. -
If you had
NodeIdPlugin
configured with options, move these options to thenodeId
field in your main editor configuration (createPlateEditor
orusePlateEditor
options). Example:// Before // const editor = usePlateEditor({ // plugins: [ // NodeIdPlugin.configure({ /* ...your options... */ }), // ], // }); // After const editor = usePlateEditor({ nodeId: { /* ...your options... */ }, // ...other editor options });
-
If you want to disable automatic node ID generation (to replicate behavior if you weren't using
NodeIdPlugin
before), setnodeId: false
in your editor configuration.
-
-
@platejs/[email protected]
- #4327 by @zbeyens –
- Package
@udecode/plate-normalizers
has been deprecated. - Its plugins have been moved to
platejs
(which is re-exported viaplatejs
). - Migration:
- Remove
@udecode/plate-normalizers
from your dependencies. - Update import paths to use
platejs
- Remove
- Package
@platejs/[email protected]
- #4327 by @zbeyens –
- Renamed all
@udecode/plate-*
packages to@platejs/*
. Replace@udecode/plate-
with@platejs/
in your code.
- Renamed all
@platejs/[email protected]
-
#4327 by @zbeyens – Package
@udecode/plate-reset-node
has been deprecated. Its functionality (e.g.,ResetNodePlugin
) is now exclusively configured using therules.break
andrules.delete
options on plugin definitions. Migration:- Remove
@udecode/plate-reset-node
from your dependencies. - Remove any usage of
ResetNodePlugin
from your project. - Configure reset behaviors directly on the relevant plugins by defining
rules.break
and/orrules.delete
.
Example: Resetting a Blockquote to a Paragraph
ResetNodePlugin.configure({ options: { rules: [ { types: [BlockquotePlugin.key], defaultType: ParagraphPlugin.key, hotkey: 'Enter', predicate: (editor) => editor.api.isEmpty(editor.selection, { block: true }), }, ], }, }); // After BlockquotePlugin.configure({ rules: { break: { empty: 'reset' }, delete: { start: 'reset' }, }, });
For custom reset logic (previously
onReset
):// Before ResetNodePlugin.configure({ options: { rules: [ { types: [CodeBlockPlugin.key], defaultType: ParagraphPlugin.key, hotkey: 'Enter', predicate: isCodeBlockEmpty, onReset: unwrapCodeBlock, }, ], }, }); // After CodeBlockPlugin.configure({ rules: { delete: { empty: 'reset' }, }, }).overrideEditor(({ editor, tf: { resetBlock } }) => ({ transforms: { resetBlock(options) { if ( editor.api.block({ at: options?.at, match: { type: editor.getType(CodeBlockPlugin.key) }, }) ) { unwrapCodeBlock(editor); return; } return resetBlock(options); }, }, }));
- Remove
@platejs/[email protected]
- #4327 by @zbeyens –
- Renamed all
@udecode/plate-*
packages to@platejs/*
. Replace@udecode/plate-
with@platejs/
in your code.
- Renamed all
@platejs/[email protected]
-
- The following plugins now default to
editOnly: true
. This means their core functionalities (handlers, rendering injections, etc.) will be disabled when the editor is in read-only mode. To override this behavior for a specific plugin, configure itseditOnly
field. For example,SomePlugin.configure({ editOnly: false })
.
- The following plugins now default to
-
- Package
@udecode/plate-select
has been deprecated. SelectOnBackspacePlugin
has been removed. This behavior is now built into Plate by default: delete (backward/forward) at the start of a block will select the previous/next void block instead of removing it.DeletePlugin
has been removed. This behavior is now built into Plate by default: delete (backward/forward) from an empty block will remove it instead of merging.RemoveEmptyNodesPlugin
has been removed. This behavior is now available through therules: { normalize: { removeEmpty: true } }
configuration on individual plugins.- Migration:
- Remove
@udecode/plate-select
from your dependencies. - Remove any usage of
SelectOnBackspacePlugin
,DeletePlugin
from your project. - Replace
RemoveEmptyNodesPlugin.configure({ options: { types: ['custom'] } })
withCustomPlugin.configure({ rules: { normalize: { removeEmpty: true } } })
. This is used by ourLinkPlugin
.
- Remove
- Package
@platejs/[email protected]
-
- The following plugins now default to
editOnly: true
. This means their core functionalities (handlers, rendering injections, etc.) will be disabled when the editor is in read-only mode. To override this behavior for a specific plugin, configure itseditOnly
field. For example,SomePlugin.configure({ editOnly: false })
.
- The following plugins now default to
-
- Renamed all
@udecode/plate-*
packages to@platejs/*
. Replace@udecode/plate-
with@platejs/
in your code.
- Renamed all
@platejs/[email protected]
-
- The following plugins now default to
editOnly: true
. This means their core functionalities (handlers, rendering injections, etc.) will be disabled when the editor is in read-only mode. To override this behavior for a specific plugin, configure itseditOnly
field. For example,SomePlugin.configure({ editOnly: false })
.
- The following plugins now default to
-
- Renamed all
@udecode/plate-*
packages to@platejs/*
. Replace@udecode/plate-
with@platejs/
in your code.
- Renamed all
-
- The type
TSlashInputElement
has been removed. - Use
TComboboxInputElement
fromplatejs
instead for Slash Command input elements, as slash command functionality is built upon the combobox.
- The type
@platejs/[email protected]
- #4327 by @zbeyens –
- Renamed all
@udecode/plate-*
packages to@platejs/*
. Replace@udecode/plate-
with@platejs/
in your code.
- Renamed all
@platejs/[email protected]
- #4327 by @zbeyens –
- Renamed all
@udecode/plate-*
packages to@platejs/*
. Replace@udecode/plate-
with@platejs/
in your code.
- Renamed all
@platejs/[email protected]
- #4327 by @zbeyens –
- Renamed all
@udecode/plate-*
packages to@platejs/*
. Replace@udecode/plate-
with@platejs/
in your code.
- Renamed all
@platejs/[email protected]
- #4327 by @zbeyens –
- Renamed all
@udecode/plate-*
packages to@platejs/*
. Replace@udecode/plate-
with@platejs/
in your code.
- Renamed all
@platejs/[email protected]
- #4327 by @zbeyens –
- Renamed all
@udecode/plate-*
packages to@platejs/*
. Replace@udecode/plate-
with@platejs/
in your code.
- Renamed all
@platejs/[email protected]
- #4327 by @zbeyens –
- Renamed all
@udecode/plate-*
packages to@platejs/*
. Replace@udecode/plate-
with@platejs/
in your code.
- Renamed all
@platejs/[email protected]
- #4327 by @zbeyens –
- Renamed all
@udecode/plate-*
packages to@platejs/*
. Replace@udecode/plate-
with@platejs/
in your code.
- Renamed all
@platejs/[email protected]
-
- The following plugins now default to
editOnly: true
. This means their core functionalities (handlers, rendering injections, etc.) will be disabled when the editor is in read-only mode. To override this behavior for a specific plugin, configure itseditOnly
field. For example,SomePlugin.configure({ editOnly: false })
.
- The following plugins now default to
-
- Package
@udecode/plate-trailing-block
has been deprecated. - Its functionality (e.g.,
TrailingBlockPlugin
) has been moved to@platejs/utils
(which is re-exported viaplatejs
). - Migration:
- Remove
@udecode/plate-trailing-block
from your dependencies. - Update import paths to use
platejs
(e.g.,import { TrailingBlockPlugin } from 'platejs';
).
- Remove
- Package
@platejs/[email protected]
On This Page
49.0.0[email protected]@platejs/[email protected]Minor Changes@platejs/[email protected]Minor Changes@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]@platejs/[email protected]