@wordpress/editor
The @wordpress/editor package provides a WordPress post-aware editor implementation. It extends @wordpress/block-editor with WordPress-specific functionality, integrating with the REST API and Core Data.
Installation
npm install @wordpress/editor --save
Architecture Position
The @wordpress/editor is the second layer in Gutenberg’s architecture:
Block Editor
Generic, WordPress-agnostic (@wordpress/block-editor)
Editor (Current Layer)
WordPress post-type aware (@wordpress/editor)
Implementations
Full editor screens (@wordpress/edit-post, @wordpress/edit-site)
This package:
Knows about WordPress posts and post types
Integrates with @wordpress/core-data
Handles post loading and saving
Provides post-specific UI components
How It Works
The editor flow:
Parse : Convert post content HTML to block representation
Render : Display blocks in the editor with UI controls
Update : Modify block state as user edits
Serialize : Convert blocks back to HTML
Save : Persist to WordPress via REST API
import { parse , serialize } from '@wordpress/blocks' ;
// Parse post content into blocks
const blocks = parse ( post . content . raw );
// User edits blocks in the editor...
// Serialize blocks back to HTML
const content = serialize ( blocks );
// Save to post_content field
Quick Start
EditorProvider
The root component for post editing:
import { EditorProvider } from '@wordpress/editor' ;
import { SlotFillProvider } from '@wordpress/components' ;
function MyPostEditor ( { post , settings } ) {
return (
< SlotFillProvider >
< EditorProvider
post = { post }
settings = { settings }
>
{ /* Your editor UI */ }
</ EditorProvider >
</ SlotFillProvider >
);
}
The post object to edit:
id: Post ID
type: Post type
content: Post content
title: Post title
Other post fields
Optional template object wrapping the post (for posts/pages with templates)
Editor settings. Extends @wordpress/block-editor settings with post-specific options
Child components to render within the editor context
Post Components
PostTitle
Editable post title input.
import { PostTitle } from '@wordpress/editor' ;
function EditorHeader () {
return (
< div className = "editor-header" >
< PostTitle />
</ div >
);
}
PostTextEditor
Text mode editor (HTML view).
import { PostTextEditor } from '@wordpress/editor' ;
< PostTextEditor />
DocumentBar
Navigation bar showing document title and back button.
import { DocumentBar } from '@wordpress/editor' ;
< DocumentBar
title = "Custom Title"
icon = { myIcon }
/>
Document title (defaults to post/template title)
Post Metadata Components
PostExcerpt
Post excerpt editor.
import { PostExcerpt } from '@wordpress/editor' ;
< PostExcerpt
hideLabelFromVision = { false }
updateOnBlur = { true }
/>
Whether to visually hide the label
Whether to update on blur instead of on change
PostFeaturedImage
Featured image selector.
import { PostFeaturedImage } from '@wordpress/editor' ;
< PostFeaturedImage />
PostAuthor
Post author selector.
import { PostAuthor } from '@wordpress/editor' ;
< PostAuthor />
PostSchedule
Post scheduling controls.
import { PostSchedule } from '@wordpress/editor' ;
< PostSchedule onClose = { () => {} } />
PostVisibility
Post visibility controls (public, private, password-protected).
import { PostVisibility } from '@wordpress/editor' ;
< PostVisibility onClose = { () => {} } />
PostFormat
Post format selector.
import { PostFormat } from '@wordpress/editor' ;
< PostFormat />
PostSticky
Sticky post toggle.
import { PostSticky } from '@wordpress/editor' ;
< PostSticky />
Taxonomy Components
PostTaxonomies
Renders all taxonomies for the post.
import { PostTaxonomies } from '@wordpress/editor' ;
< PostTaxonomies
taxonomyWrapper = { ( content , taxonomy ) => (
< div key = { taxonomy . slug } > { content } </ div >
) }
/>
PostTaxonomiesHierarchicalTermSelector
Hierarchical taxonomy selector (like categories).
import { PostTaxonomiesHierarchicalTermSelector } from '@wordpress/editor' ;
< PostTaxonomiesHierarchicalTermSelector slug = "category" />
Taxonomy slug (e.g., ‘category’)
PostTaxonomiesFlatTermSelector
Flat taxonomy selector (like tags).
import { PostTaxonomiesFlatTermSelector } from '@wordpress/editor' ;
< PostTaxonomiesFlatTermSelector slug = "post_tag" />
Taxonomy slug (e.g., ‘post_tag’)
Publishing Components
PostPublishButton
Publish/update button.
import { PostPublishButton } from '@wordpress/editor' ;
< PostPublishButton />
PostPublishPanel
Pre-publish checklist panel.
import { PostPublishPanel } from '@wordpress/editor' ;
< PostPublishPanel />
PostSavedState
Shows save status and save button.
import { PostSavedState } from '@wordpress/editor' ;
< PostSavedState forceIsDirty = { false } />
Force the post to be marked as dirty
PostPreviewButton
Preview button.
import { PostPreviewButton } from '@wordpress/editor' ;
< PostPreviewButton
className = "editor-preview-button"
textContent = "Preview"
onPreview = { () => console . log ( 'Previewing...' ) }
/>
PostSwitchToDraftButton
Switch to draft button (for published posts).
import { PostSwitchToDraftButton } from '@wordpress/editor' ;
< PostSwitchToDraftButton />
PostTrash
Move to trash button.
import { PostTrash } from '@wordpress/editor' ;
< PostTrash
onActionPerformed = { () => {
// Navigate away or show success message
} }
/>
Panel Components
PostExcerptPanel
Excerpt panel for sidebar.
import { PostExcerptPanel } from '@wordpress/editor' ;
< PostExcerptPanel />
PostFeaturedImagePanel
Featured image panel for sidebar.
import { PostFeaturedImagePanel } from '@wordpress/editor' ;
< PostFeaturedImagePanel withPanelBody = { true } />
PostTaxonomiesPanel
Taxonomies panel for sidebar.
import { PostTaxonomiesPanel } from '@wordpress/editor' ;
< PostTaxonomiesPanel />
PostDiscussionPanel
Comments and pingbacks panel.
import { PostDiscussionPanel } from '@wordpress/editor' ;
< PostDiscussionPanel />
PostLastRevisionPanel
Post revisions panel.
import { PostLastRevisionPanel } from '@wordpress/editor' ;
< PostLastRevisionPanel />
PageAttributesPanel
Page attributes (parent, order, template).
import { PageAttributesPanel } from '@wordpress/editor' ;
< PageAttributesPanel />
Plugin Extension Points
PluginDocumentSettingPanel
Add custom panels to document settings.
import { PluginDocumentSettingPanel } from '@wordpress/editor' ;
import { registerPlugin } from '@wordpress/plugins' ;
const MyPanel = () => (
< PluginDocumentSettingPanel
name = "my-custom-panel"
title = "My Custom Settings"
className = "my-custom-panel"
>
< p > Custom panel content </ p >
</ PluginDocumentSettingPanel >
);
registerPlugin ( 'my-custom-panel' , { render: MyPanel } );
PluginPostStatusInfo
Add items to post status panel.
import { PluginPostStatusInfo } from '@wordpress/editor' ;
import { registerPlugin } from '@wordpress/plugins' ;
const MyStatusInfo = () => (
< PluginPostStatusInfo className = "my-status-info" >
< p > Word count: 500 </ p >
</ PluginPostStatusInfo >
);
registerPlugin ( 'my-status-info' , { render: MyStatusInfo } );
PluginPrePublishPanel
Add panel to pre-publish checklist.
import { PluginPrePublishPanel } from '@wordpress/editor' ;
import { registerPlugin } from '@wordpress/plugins' ;
const MyPrePublishPanel = () => (
< PluginPrePublishPanel
title = "Pre-publish Checklist"
initialOpen = { true }
>
< p > Review your content before publishing </ p >
</ PluginPrePublishPanel >
);
registerPlugin ( 'my-prepublish-panel' , { render: MyPrePublishPanel } );
PluginPostPublishPanel
Add panel to post-publish flow.
import { PluginPostPublishPanel } from '@wordpress/editor' ;
import { registerPlugin } from '@wordpress/plugins' ;
const MyPostPublishPanel = () => (
< PluginPostPublishPanel
title = "Share Your Post"
initialOpen = { true }
>
< p > Share on social media... </ p >
</ PluginPostPublishPanel >
);
registerPlugin ( 'my-postpublish-panel' , { render: MyPostPublishPanel } );
Add custom sidebar.
import { PluginSidebar } from '@wordpress/editor' ;
import { registerPlugin } from '@wordpress/plugins' ;
import { PanelBody } from '@wordpress/components' ;
const MySidebar = () => (
< PluginSidebar
name = "my-sidebar"
title = "My Sidebar"
icon = "admin-plugins"
>
< PanelBody >
< p > Sidebar content </ p >
</ PanelBody >
</ PluginSidebar >
);
registerPlugin ( 'my-sidebar' , { render: MySidebar } );
Unique sidebar identifier
Whether sidebar can be pinned (automatically renders menu item)
Add item to block settings menu.
import { PluginBlockSettingsMenuItem } from '@wordpress/editor' ;
import { registerPlugin } from '@wordpress/plugins' ;
const MyBlockMenuItem = () => (
< PluginBlockSettingsMenuItem
allowedBlocks = { [ 'core/paragraph' ] }
icon = "admin-plugins"
label = "Custom Action"
onClick = { () => console . log ( 'Clicked!' ) }
/>
);
registerPlugin ( 'my-block-menu-item' , { render: MyBlockMenuItem } );
Block names to show this item for
Add item to More Menu (three dots).
import { PluginMoreMenuItem } from '@wordpress/editor' ;
import { registerPlugin } from '@wordpress/plugins' ;
const MyMoreMenuItem = () => (
< PluginMoreMenuItem
icon = "admin-plugins"
onClick = { () => console . log ( 'More menu clicked' ) }
>
Custom Action
</ PluginMoreMenuItem >
);
registerPlugin ( 'my-more-menu-item' , { render: MyMoreMenuItem } );
Monitoring Components
AutosaveMonitor
Monitors changes and triggers autosave.
import { AutosaveMonitor } from '@wordpress/editor' ;
< AutosaveMonitor interval = { 30000 } />
Autosave interval in milliseconds (e.g., 30000 for 30 seconds)
The logic checks for changes every interval seconds. If changes are detected and the post is autosaveable, it calls the autosave action.
LocalAutosaveMonitor
Manages browser-based local autosaves.
import { LocalAutosaveMonitor } from '@wordpress/editor' ;
< LocalAutosaveMonitor />
Automatically handles:
Creating local autosaves in sessionStorage
Prompting to restore local autosaves
Clearing local autosaves after successful save
PostLockedModal
Displays when another user is editing the post.
import { PostLockedModal } from '@wordpress/editor' ;
< PostLockedModal />
Shows lock information and options to take over or exit.
UnsavedChangesWarning
Warns before leaving with unsaved changes.
import { UnsavedChangesWarning } from '@wordpress/editor' ;
< UnsavedChangesWarning />
Keyboard Shortcuts
EditorKeyboardShortcuts
Registers editor keyboard shortcuts.
import { EditorKeyboardShortcuts } from '@wordpress/editor' ;
< EditorKeyboardShortcuts />
Provides shortcuts for:
Toggle editor mode (Ctrl+Shift+Alt+M)
Save post (Ctrl+S)
Undo/Redo (Ctrl+Z / Ctrl+Shift+Z)
Toggle distraction-free mode
Toggle list view
Toggle sidebar
History Controls
EditorHistoryUndo
Undo button.
import { EditorHistoryUndo } from '@wordpress/editor' ;
< EditorHistoryUndo />
EditorHistoryRedo
Redo button.
import { EditorHistoryRedo } from '@wordpress/editor' ;
< EditorHistoryRedo />
Document Utilities
DocumentOutline
Displays document heading structure.
import { DocumentOutline } from '@wordpress/editor' ;
< DocumentOutline
onSelect = { ( block ) => {
// Navigate to block
} }
hasOutlineItemsDisabled = { false }
/>
TableOfContents
Table of contents dropdown.
import { TableOfContents } from '@wordpress/editor' ;
< TableOfContents
hasOutlineItemsDisabled = { false }
/>
CharacterCount
Returns character count of post content.
import { CharacterCount } from '@wordpress/editor' ;
function MyComponent () {
return (
< div >
Characters: < CharacterCount />
</ div >
);
}
TimeToRead
Estimated reading time.
import { TimeToRead } from '@wordpress/editor' ;
< TimeToRead />
Utility Functions
cleanForSlug
Cleans a string for use as a post slug.
import { cleanForSlug } from '@wordpress/editor' ;
const slug = cleanForSlug ( 'My Post Title!' );
// "my-post-title"
This approximates what WordPress sanitize_title() does but is client-side only.
Upload media files with current post ID.
import { mediaUpload } from '@wordpress/editor' ;
mediaUpload ( {
allowedTypes: [ 'image' ],
filesList: files ,
onFileChange : ( [ media ] ) => {
console . log ( 'Uploading:' , media );
},
onSuccess : ( [ media ] ) => {
console . log ( 'Uploaded:' , media );
},
onError : ( error ) => {
console . error ( 'Upload failed:' , error );
},
} );
Check Components
Conditional rendering components:
PostTypeSupportCheck
import { PostTypeSupportCheck } from '@wordpress/editor' ;
< PostTypeSupportCheck supportKeys = "excerpt" >
{ /* Only rendered if post type supports excerpts */ }
< PostExcerpt />
</ PostTypeSupportCheck >
PostAuthorCheck
import { PostAuthorCheck } from '@wordpress/editor' ;
< PostAuthorCheck >
< PostAuthor />
</ PostAuthorCheck >
PostFeaturedImageCheck
import { PostFeaturedImageCheck } from '@wordpress/editor' ;
< PostFeaturedImageCheck >
< PostFeaturedImage />
</ PostFeaturedImageCheck >
ThemeSupportCheck
import { ThemeSupportCheck } from '@wordpress/editor' ;
< ThemeSupportCheck supportKeys = "post-thumbnails" >
{ /* Only rendered if theme supports post thumbnails */ }
</ ThemeSupportCheck >
Saved States
EntitiesSavedStates
Manages saving multiple entities (post + template).
import { EntitiesSavedStates } from '@wordpress/editor' ;
< EntitiesSavedStates
close = { () => setIsOpen ( false ) }
renderDialog = { true }
variant = "inline"
/>
Function to close the dialog
Whether to render as a modal dialog
'inline' renders action buttons at the end instead of start
Error Boundary
ErrorBoundary
Catches JavaScript errors in child components.
import { ErrorBoundary } from '@wordpress/editor' ;
< ErrorBoundary >
{ /* Your components */ }
</ ErrorBoundary >
DataViews Integration
registerEntityField
Register custom DataViews fields (experimental).
import { registerEntityField } from '@wordpress/editor' ;
registerEntityField ( 'postType' , 'post' , {
id: 'custom-field' ,
label: 'Custom Field' ,
getValue : ( { item } ) => item . meta . custom_field ,
} );
registerEntityAction
Register custom DataViews actions (experimental).
import { registerEntityAction } from '@wordpress/editor' ;
registerEntityAction ( 'postType' , 'post' , {
id: 'custom-action' ,
label: 'Custom Action' ,
callback : ( items ) => {
// Perform action
},
} );
Store
The editor package includes a data store:
import { store as editorStore } from '@wordpress/editor' ;
import { useSelect , useDispatch } from '@wordpress/data' ;
function MyComponent () {
const { title , isDirty } = useSelect ( ( select ) => ( {
title: select ( editorStore ). getEditedPostAttribute ( 'title' ),
isDirty: select ( editorStore ). isEditedPostDirty (),
} ), [] );
const { editPost , savePost } = useDispatch ( editorStore );
return (
< div >
< input
value = { title }
onChange = { ( e ) => editPost ( { title: e . target . value } ) }
/>
< button onClick = { savePost } disabled = { ! isDirty } >
Save
</ button >
</ div >
);
}
TypeScript
Type definitions are included:
import type { EditorSettings } from '@wordpress/editor' ;
const settings : EditorSettings = {
alignWide: true ,
colors: [
{ name: 'Red' , slug: 'red' , color: '#ff0000' }
],
};
Dependencies
Key dependencies:
@wordpress/block-editor - Generic block editor
@wordpress/blocks - Block API
@wordpress/core-data - WordPress data entities
@wordpress/data - State management
@wordpress/components - UI components
@wordpress/element - React abstraction
And 30+ other packages
See package.json for the complete list.
Resources
Editor Handbook Complete editor documentation
Plugin Extension Points Extending the editor with plugins
GitHub Repository Source code and issue tracker
Core Data Package Learn about WordPress data management