WordPress wp_editor Example: Add a Rich Text Field Safely
Render and store rich text safely with wp_editor() on a stable WordPress admin screen without breaking editor behavior.
Published
May 4, 2026
Reading Time
2 min read
Updated
May 4, 2026

Implementation Notes
Extension points, code paths, and implementation choices that should survive contact with production.
Best For
WordPress developers, agencies, and technical teams building custom plugin or theme functionality with cleaner operational defaults.
Primary Topics
Editorial Focus
Build Pattern: Extension points, code paths, and implementation choices that should survive contact with production. Updated on May 4, 2026.
Full Report
Last reviewed: May 4, 2026
Rich text input is one of those features teams add late and often wire up badly. They start with a plain textarea, then eventually need formatting, links, and media controls for curated snippets. wp_editor() is the supported way to render the WordPress editor, but placement and storage rules matter if the field is supposed to stay reliable in production.
This guide shows how to use wp_editor() on a plugin settings screen, how to save the result safely, and why moving TinyMCE-powered editors around the DOM is where implementations often go wrong.
Render the editor in a stable settings screen context
<?php
$value = get_option( 'vulnwp_footer_notice_html', '' );
wp_editor(
$value,
'vulnwp_footer_notice_html',
array(
'textarea_name' => 'vulnwp_footer_notice_html',
'media_buttons' => false,
'textarea_rows' => 8,
)
);
This keeps the editor in a stable screen layout where WordPress can initialize the required scripts and controls normally.
Sanitize the saved value for the content you actually allow
<?php
if ( isset( $_POST['vulnwp_footer_notice_html'] ) ) {
$raw = wp_unslash( $_POST['vulnwp_footer_notice_html'] );
$safe = wp_kses_post( $raw );
update_option( 'vulnwp_footer_notice_html', $safe, false );
}
The editor UI does not eliminate the need for output discipline. If the stored content is supposed to allow post-style HTML, wp_kses_post() is a reasonable fit. If the use case allows less HTML than a normal post body, a tighter custom allowlist is safer.
Do not assume it behaves well inside every meta box pattern
The official reference warns that once TinyMCE is initialized it cannot be safely moved around the DOM. That is why wp_editor() on a normal settings screen is usually simpler than trying to force a complex editor instance into a UI pattern that repositions markup after page load.
Keep rich text fields narrow in purpose
A rich text field should exist because the product needs formatted content, not because plain strings became inconvenient. If the field is just a heading, badge, or status label, a text input is easier to validate and audit.
Common mistakes
- Saving raw editor output without sanitization. The editor is an input surface, not a trust boundary.
- Using a rich text editor for values that should be plain text. This expands complexity without adding value.
- Embedding the editor in a layout that moves it after initialization. TinyMCE does not like that lifecycle.
- Turning on media controls without a real content workflow. That adds UI noise and broader capabilities.
Production checklist
- Use
wp_editor()in a stable admin context. - Set an explicit
textarea_nameso saving logic stays predictable. - Sanitize saved content according to the allowed HTML model.
- Reserve rich text fields for content that truly needs formatting.
- Test both the Visual and Text modes if the editor will be used operationally.
Related reading
Pair this with the wp_kses guide when deciding what HTML to allow, and with the Settings API article when the editor lives inside a real plugin options flow.


