Using the WordPress WYSIWYG editor within custom Widgets · vanrossum.dev    

       vanrossum.dev 

 Article

Using the WordPress WYSIWYG editor within custom Widgets
========================================================

 ![](https://vanrossum.dev/images/jeffrey-portrait.webp) By Jeffrey van Rossum

  vanrossum.dev  

  [      vanrossum.dev ](https://vanrossum.dev)                      

  [ ← Writing ](https://vanrossum.dev/posts)   [ ← Writing ](https://vanrossum.dev/posts) [ Going the JavaScript route ](#going-the-javascript-route) [ Initializing multiple wp.editor instances ](#initializing-multiple-wpeditor-instances) 

Sometimes you want to create a custom widget for your WordPress theme or plugin. And sometimes, you might want to include the tiny WYSIWYG editor like the one that is within the Text widget WordPress offers out of the box.

Now, you might think this is easy to do. But it turns out, it's not. The interwebs is full of threads and articles of using the editor within widgets, with all kinds of trickery and workarounds.

One might think, why not just use the `wp_editor` [function](https://developer.wordpress.org/reference/functions/wp_editor/). And this will indeed work fine for things like settings pages. But for widgets, you'd be running into issues mostly because widgets are handled through AJAX-requests. And all [workarounds](https://wordpress.stackexchange.com/a/96636) you'll find online don't seem to be [working anymore](https://wordpress.stackexchange.com/questions/227165/wp-editor-in-widget-breaks-after-save-no-buttons-and-visual-tab-broken).

Going the JavaScript route
--------------------------

Now instead of using the `wp_editor` function, I tried getting it to work with the `wp.editor` [JavaScript object](https://codex.wordpress.org/Javascript_Reference/wp.editor). And I seem to have a working solution now. Maybe not perfect, but at least it works.

First, to be able to use this function, we need to include the necessary editor scripts. Also, to be able to add our own JavaScript, we'll add a file `wp-editor-widgets.js` (but you can call it differently if you want of course).

```php
function custom_widgets_widget_editor_script() {
    global $pagenow;

    if ( 'widgets.php' === $pagenow || 'customize.php' === $pagenow ) {
        wp_enqueue_editor();

        wp_enqueue_script( 'wp-editor-widgets', get_stylesheet_directory_uri() . '/js/wp-editor-widgets.js', array( 'jquery' ), false, false );
    }
}

add_action( 'admin_enqueue_scripts', 'custom_widgets_widget_editor_script' );

```

Initializing multiple wp.editor instances
-----------------------------------------

In our custom widget, we'll just add a textarea. To identify the editors in our script, we'll add a CSS-class to the textarea called `custom-widget-wp-editor`.

So within your widget a textarea that needs to become an editor, can look something like this:

```php

```

Let's get started with the script. Be sure to wrap your script within document ready function.

```javascript
jQuery(document).ready(function ($) {
    // Our script.
});

```

In our script, we'll make a function to collect all textareas that we need to convert to editors.

```javascript
function custom_widgets_get_editors() {
    let editors = [];

    $(document).find("#customize-theme-controls .custom-widget-wp-editor, #widgets-right .custom-widget-wp-editor").each(function () {
        editors.push($(this).attr('id'));
    });

    return editors;
}

```

We target the widget areas both in the Customizer view and the regular widgets view.

Next, we'll initialize our editors.

```javascript
function custom_widgets_init_editors() {
    custom_widgets_get_editors().forEach(function (id) {
        wp.editor.initialize($('#' + id).attr('id'), {
            tinymce: {
                wpautop: true
            },
            quicktags: true,
            mediaButtons: true
        });
    });
}

// Init the function.
custom_widgets_init_editors();

```

Now this will already display our editors, but it will result in the values not being submitted. We can solve this by triggering a `click` on the HTML-tab. Let's add it to our `custom_widgets_init_editors` function.

```javascript
function custom_widgets_init_editors() {
    custom_widgets_get_editors().forEach(function (id) {
        wp.editor.initialize($('#' + id).attr('id'), {
            tinymce: {
                wpautop: true
            },
            quicktags: true,
            mediaButtons: true
        });
    });

    // To prevent the editor from not submitting the value, we click the switch html tab.
    $(document).contents().find('.widget-control-save').off().on('click', function (e) {
        custom_widgets_get_editors().forEach(function (editor) {
            let form = $('#' + editor).closest('form');
            form.find('.switch-html').click();
    });
});

```

Now if we add or update our widget, we'll have to re-initialize our editors. Otherwise, since widgets are handled through AJAX-requests, our editors will break. But before we can re-initialize them, we'll need to remove the current instances.

```js
function custom_widgets_remove_editors() {
    custom_widgets_get_editors().forEach(function (id) {
        wp.editor.remove(id);
    });
}

```

Finally, we listen to the widget events and trigger the necessary functions.

```js
$(document).on('widget-updated widget-added', function () {
    custom_widgets_remove_editors();
    custom_widgets_init_editors();
});

```

Just want a gist? [Here](https://gist.github.com/jeffreyvr/434fe738d9a9d074e073ec14da672e16) it is.

  ![](https://vanrossum.dev/images/jeffrey-portrait.webp) Jeffrey van Rossum [@jeffreyrossum](https://x.com/jeffreyrossum) 

 share [𝕏](https://twitter.com/intent/tweet?url=https%3A%2F%2Fvanrossum.dev%2Fposts%2Fusing-the-wordpress-wysiwyg-editor-within-custom-widgets&text=Using+the+WordPress+WYSIWYG+editor+within+custom+Widgets) [WhatsApp](https://wa.me/?text=Using+the+WordPress+WYSIWYG+editor+within+custom+Widgets+https%3A%2F%2Fvanrossum.dev%2Fposts%2Fusing-the-wordpress-wysiwyg-editor-within-custom-widgets) [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fvanrossum.dev%2Fposts%2Fusing-the-wordpress-wysiwyg-editor-within-custom-widgets) 

   © 2026 Jeffrey van Rossum 

  vanrossum.dev vanrossum.dev
