Skip to main content

@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
Current Version: 14.40.1This package assumes an ES2015+ environment. Include the polyfill from @wordpress/babel-preset-default if needed.

Architecture Position

The @wordpress/editor is the second layer in Gutenberg’s architecture:
1

Block Editor

Generic, WordPress-agnostic (@wordpress/block-editor)
2

Editor (Current Layer)

WordPress post-type aware (@wordpress/editor)
3

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:
  1. Parse: Convert post content HTML to block representation
  2. Render: Display blocks in the editor with UI controls
  3. Update: Modify block state as user edits
  4. Serialize: Convert blocks back to HTML
  5. 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>
  );
}
post
Object
required
The post object to edit:
  • id: Post ID
  • type: Post type
  • content: Post content
  • title: Post title
  • Other post fields
__unstableTemplate
Object
Optional template object wrapping the post (for posts/pages with templates)
settings
Object
Editor settings. Extends @wordpress/block-editor settings with post-specific options
children
React.ReactNode
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 }
/>
title
string
Document title (defaults to post/template title)
icon
IconType
Icon to display

Post Metadata Components

PostExcerpt

Post excerpt editor.
import { PostExcerpt } from '@wordpress/editor';

<PostExcerpt
  hideLabelFromVision={ false }
  updateOnBlur={ true }
/>
hideLabelFromVision
boolean
Whether to visually hide the label
updateOnBlur
boolean
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" />
slug
string
required
Taxonomy slug (e.g., ‘category’)

PostTaxonomiesFlatTermSelector

Flat taxonomy selector (like tags).
import { PostTaxonomiesFlatTermSelector } from '@wordpress/editor';

<PostTaxonomiesFlatTermSelector slug="post_tag" />
slug
string
required
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 } />
forceIsDirty
boolean
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 } );
name
string
required
Unique panel identifier
title
string
Panel title
className
string
Additional CSS class
icon
WPBlockTypeIconRender
Panel icon

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 } );

PluginSidebar

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 } );
name
string
required
Unique sidebar identifier
title
string
required
Sidebar title
icon
WPBlockTypeIconRender
Sidebar icon
isPinnable
boolean
Whether sidebar can be pinned (automatically renders menu item)

PluginBlockSettingsMenuItem

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 } );
allowedBlocks
Array
Block names to show this item for
icon
WPBlockTypeIconRender
Menu item icon
label
string
required
Menu item text
onClick
Function
required
Click handler

PluginMoreMenuItem

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 } />
interval
number
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"
string
string
required
Title or slug to process
return
string
Processed slug string
This approximates what WordPress sanitize_title() does but is client-side only.

mediaUpload

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"
/>
close
Function
required
Function to close the dialog
renderDialog
boolean
Whether to render as a modal dialog
variant
string
'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

Build docs developers (and LLMs) love