Any ideal way how to change Gutenberg's categories checkboxes to radio inputs? I have tried using this plugin: Categories Metabox Enhanced.

But it doesn't work fully well with Gutenberg, meaning my conditions to show some field when a term is checked doesn't work. Also this plugin adds an extra meta box without replacing Gutenberg's default categories box.

enter image description here

3 Answers 3


Fortunately there is a hook that we can use to customize what component is used to render the taxonomy panels called editor.PostTaxonomyType.

Gutenberg renders taxonomy panels with a component called PostTaxonomies, which really just checks whether the taxonomy is heirarchical or not, and passes the props along to either the HierarchicalTermSelector or FlatTermSelector components accordingly. Normally, these two components don't appear to be exposed in the Gutenberg API, except for within the editor.PostTaxonomyType hook, which passes the relevant component as the 1st argument.

From there, all we have to do is extend the component, override the renderTerms method to change the input type from checkbox to radio, and override the onChange method to only return one selected term.

Unfortunately, extending the class within the hook seemed to cause a noticable performance hit, but storing the extended class in the window seemed to mitigate that.



 * External dependencies
import { unescape as unescapeString } from 'lodash';

function customizeTaxonomySelector( OriginalComponent ) {
    return function( props ) {
        if ( props.slug === 'my_taxonomy') {
            if ( ! window.HierarchicalTermRadioSelector ) {
                window.HierarchicalTermRadioSelector = class HierarchicalTermRadioSelector extends OriginalComponent {
                    // Return only the selected term ID
                    onChange( event ) {
                        const { onUpdateTerms, taxonomy } = this.props;
                        const termId = parseInt( event.target.value, 10 );
                        onUpdateTerms( [ termId ], taxonomy.rest_base );

                    // Copied from HierarchicalTermSelector, changed input type to radio
                    renderTerms( renderedTerms ) {
                        const { terms = [] } = this.props;
                        return renderedTerms.map( ( term ) => {
                            const id = `editor-post-taxonomies-hierarchical-term-${ term.id }`;
                            return (
                                <div key={ term.id } className="editor-post-taxonomies__hierarchical-terms-choice">
                                        id={ id }
                                        checked={ terms.indexOf( term.id ) !== -1 }
                                        value={ term.id }
                                        onChange={ this.onChange }
                                    <label htmlFor={ id }>{ unescapeString( term.name ) }</label>
                                    { !! term.children.length && <div className="editor-post-taxonomies__hierarchical-terms-subchoices">{ this.renderTerms( term.children ) }</div> }
                        } );
            return <window.HierarchicalTermRadioSelector { ...props } />;
        return <OriginalComponent { ...props } />;
wp.hooks.addFilter( 'editor.PostTaxonomyType', 'my-custom-plugin', customizeTaxonomySelector );
  • 1
    Thanks for the thoughtful and complete working solution to this problem, i have implemented this approach to replace custom taxonomy checkboxes with a selectControl component with little effort.
    – luckyape
    Commented Oct 7, 2019 at 19:47
  • My plugin Radio Buttons for Taxonomies uses this filter to turn the checkboxes into radio buttons. They are making some changes to the HierarchicalTermSelector component and I'm struggling to update. Can you still extend the original component if HierarchicalTermSelector is a function and not a class? Commented Aug 3, 2021 at 16:28
  • 1
    Currently I am copying over the entire script file and rebuilding it with slight mods, but that seems really onerous when I only need to change a few parts like you have in your answer. Commented Aug 3, 2021 at 16:31
  • 1
    @paulthewalton Great start with your snippet. I got it working but after updating Gutenberg plugin, It has stopped working and throwing recovery error. Any idea what it could be? After spending many hours but not able to fix it. Here is error. TypeError: Class constructor xs cannot be invoked without 'new' at new HierarchicalTermRadioSelector Commented Aug 25, 2021 at 2:46

Just in case someone needs the select box version, you can try the following, A slight modification to @Paul_Walton answer:

const {
} = wp.components;

function customizeTaxonomySelector(OriginalComponent) {
  return function(props) {
    if (props.slug === 'my_taxonomy') {
      if (!window.HierarchicalTermRadioSelector) {
        window.HierarchicalTermRadioSelector = class HierarchicalTermRadioSelector extends OriginalComponent {
          // Return only the selected term ID
          onChange(val) {
            const {
            } = this.props;
            const termId = parseInt(val, 10);
            onUpdateTerms([termId], taxonomy.rest_base);
          // Copied from HierarchicalTermSelector, changed input type to radio
          renderTerms(renderedTerms) {
            const {
              terms = []
            } = this.props;
            return ( < SelectControl label = {
                __('Select some users:')
              value = {
              } // e.g: value = [ 'a', 'c' ]
              onChange = {
              options = {
                renderedTerms.map((term) => {
                  return {
                    value: term.id,
                    label: term.name
        return <window.HierarchicalTermRadioSelector { ...props
      return <OriginalComponent { ...props
  wp.hooks.addFilter('editor.PostTaxonomyType', 'my-plugin', customizeTaxonomySelector);

Yes, Categories Metabox Enhanced quite cleverly adds its own custom meta boxes displaying the options of categories and custom taxonomies the way you configured it in the plugin's settings (as checkbox, radios or select).

You then additionally just need to ensure to hide the default meta boxes manually by clicking the three small dots at the top of the post edit screen to "Adjust display" and uncheck "Categories" and your custom taxonomies.

Above UI setting probably can be overridden by every other user. To programmatically remove the default category meta box from Gutenberg do the following. Source: [GitHub] Custom Taxonomy: Show in REST, Hide default Gutenberg Panel (comment).

 * Disable display of Gutenberg Post Setting UI for a specific
 * taxonomy. While this isn't the official API for this need,
 * it works for now because only Gutenberg is dependent on the
 * REST API response.
add_filter('rest_prepare_taxonomy', function ($response, $taxonomy) {
  if ('category' === $taxonomy->name) {
    $response->data['visibility']['show_ui'] = FALSE;
  return $response;
}, 10, 2);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.