Photo of a US button one should push to cross the street

Hated by some and loved by many, it is clear that the new WordPress block editor does not leave you indifferent. It has been with us for more than a month now and more plugins and themes are compatible with it.

As a plugin developer, I have to say that adapting our products to Gutenberg has not been something that can be done in a couple of days. At Nelio we’ve been following the evolution and development of the new block editor for quite some time in order to be able to maintain the same functionalities of our plugins with no significant changes.

One of the key points to be able to adapt Nelio Content to Gutenberg was the ability of adding buttons in the text blocks to continue doing the same thing we were doing with TinyMCE (the classic editor). I remind you that one of the most interesting features of Nelio Content is to allow you to select phrases within the content to share them on your social networks directly, or to mark them and then our algorithm will select the most relevant and set up a series of automatic promotional messages. I explained it to you before in this post.

Highlighting to share with Nelio Content
Highlighting sentences to share with Nelio Content is one of the key features. Here’s how you do it with the classic editor.

To include additional buttons in TinyMCE, WordPress has a pretty complete documentation. But how do we do it in Gutenberg? How do we add a button in rich text blocs in WordPress?

It is clear that keeping this functionality is key to continue providing a quality product such as Nelio Content, not only for our customers but also for ourselves, as we, too, are interested in using the sentence highlighting functionality in Gutenberg.

For this reason, I decided to open an issue in the GitHub of the Gutenberg project explaining the problem and asking for help in January 2018 (almost a year ago, at the time of publishing this post). There I asked for the possibility of adding buttons to Gutenberg’s text blocks in order to work with the selected text in such blocks.

The evolution of the issue was positive and in the end such functionality was added thanks to Gutenberg’s Format Types. Since the documentation is still quite poor (as I write this post), I’m going to explain how to add a custom button to the text blocks of the block editor, so you don’t waste your time and have an easier time than me.

You’ll find all the plugin code that adds a button to the editor in this GitHub repository. Although it’s quite simple, I’m going to explain in more detail the most important parts of this project.

The key project file is the one you will find at /src/js/gutenberg.js and that you have below:

The registerFormatType function is specific to the WordPress core and is the one that allows you to add a new format type, together with the button that triggers the action. You pass a name ('nelio/button') and a JavaScript object with arguments as parameters. Among those arguments, you have the edit method, which is the one that returns a React Element, which in our case will be the button we want to put in the block.

This button is a RichTextToolbarButton, which is nothing more than a React component of the Gutenberg editor itself that you can find defined here. This component needs an icon (which is an SVG file with Nelio’s logo, in this case), the title of the button, and a function that will be executed when the button is clicked. This function ends up calling the doTheJob function, where the selected text is retrieved and printed in the browser’s console. That’s the place where you can add any JavaScript code you want to handle that selected text.

In the icon attribute of RichTextToolbarButton you can put a string with the name of a WordPress Dashicon instead of the SVG. For the SVG to work, keep in mind that we use the svg-react-loader package that converts SVG files into React elements, which is what this React components need.

The code uses the ES6+ syntax to make it easier to understand, but to make it work you have to process it with Babel, and for that we have this configuration in webpack:

I won’t go into detail about what each line of the previous webpack configuration file is for, but if you look at it you’ll see that we use svg-react-loader for SVG files and babel-loader to process JavaScript and convert it into code that works in any browser. I’ve already talked about all these modern technologies in this post.

The result is the JavaScript file gutenberg.js that appears in /dist/js. Now what we have to do is load this file into the WordPress edit screen, using (as always) wp_enqueue_script:

Note that the script is queued in enqueue_block_editor_assets hook, which is the one that assures us that the script will be loaded only when the WordPress block editor is used.

If you want to try the code, download the GitHub project and move the folder to your WordPress within /wp-content/plugins. There, open a terminal and run npm install. You need to have NodeJS installed for everything to work and be able to include the necessary dependencies that our code requires.

When you have the dependencies, run npm run build in the terminal to generate the final code (processing the JavaScript and so on). Now you can go to your WordPress and activate the plugin we just added.

The button we just added in a rich text block in Gutenberg.
The custom button we just added in a rich text block in Gutenberg.

When you open a post for editing, you will see the new button appear in the text blocks. If you select a fragment of the text and click the button, you will see the selected text appear in the browser’s console. This is what we expected to happen as we saw in the code above.

To Know More…

This is only a minimum example of how to put a button in a text block. If you want the selected text to be modified when you click on the button, I encourage you to review the code of this plugin where several buttons with different, more complex formats are added.

On the other hand, for those of you who want to go even deeper into the subject, I recommend that you look at the code of the GhostKit plugin, which modifies Gutenberg’s default interface by adding different additional elements. It is also a code that is very well structured and easy to understand.

At some point we will have an official and detailed documentation covering all aspects of this Gutenberg features, but for now we have to read code to learn how to implement these types of modifications of the WordPress block editor. Good luck!

Featured image by Ashim D’Silva on Unsplash.

19 responses to “How to Add a Button to The Gutenberg Editor”

  1. Greg Avatar
    Greg

    Great content! Do you know if it’s possible to limit custom formatting buttons to specific blocks only? I may want to add extra formatting options to a custom block but not all blocks.

    1. Antonio Villegas Avatar

      The registerBlockType method extends all rich text components. To do what you want, if you control the custom block code you can include a BlockControls component in the edit method of the block. Otherwise you should use a filter like this one, but this is a more complex scenario (I tried to do that once, but failed).

  2. Tom Avatar
    Tom

    Thank you for your great content !

    I’m trying to create a button that will allow to edit a link like the url link button using URLPopover but adding some extra features (CSS class…) in the ToggleControl area. Would you have any idea how to proceed? I am a beginner in ReactJs. Thanks for your help

    1. Antonio Villegas Avatar

      Hi Tom. I’m sorry to say it, but you should go to check the Gutenberg code directly. There is no documentation about this particular scenario you want (at least I think so), so the answer is in the code.

  3. Tapas Avatar
    Tapas

    I have just simply installed the plugin but nothing is showing up.

    When I checked the console it says syntax error.

    1. Antonio Villegas Avatar

      Could you provide more details about the error that you get?

  4. DesignerKen Avatar
    DesignerKen

    Installed your plug-in to test. I am getting a `Uncaught SyntaxError: Cannot use import statement outside a module` in line 1 of the gutenberg.js file.

    Also needed to change the path to the JS file from “dist” to “src”

    1. Antonio Villegas Avatar

      Did you compile the code using webpack? The code won’t work if you don’t do that.

      1. DesignerKen Avatar
        DesignerKen

        Yes I have tried that. On nmp install it is looking for package.json and states no such file or directory, but then it terminal states 59 packages were installed.

        I run build, and get the same no file/dir

        1. Antonio Villegas Avatar

          I just pushed a new commit that fixes the issue. If you download the code from the GitHub repo, now it should work.

  5. Matt Avatar
    Matt

    Getting Uncaught ReferenceError: _wpThemeSettings is not defined
    at theme.min.js?ver=5.4:2
    at theme.min.js?ver=5.4:2

    1. Antonio Villegas Avatar

      Did you downloaded the code from the GitHub repo? It seems the error you have is related to your theme, isn’t it?

  6. supergiu Avatar
    supergiu

    Hi! Thank you for this post 🙂

    I tried to build gutenberg.js file but I get this error:
    Module build failed: SyntaxError: Unexpected token on <RichTextToolbarButton.

    I googled about that but I can't find a solution by myself, can you help me to debug the error?

    Thank You
    Giulia

      1. supergiu Avatar
        supergiu

        Thank you! I read your updated tutorial and it is exactly what I need but…
        I modified your process method and I’m not good enough to get it works 🙂

        My function is this:

        function processTooltip( value ) {
        const selectedText = value.text.substring( value.start, value.end );

        if ( 0 === selectedText.length ) {
        return;
        }

        onChange(
        toggleFormat(
        selectedText,
        { type: ‘gutenberg-button/tooltip’ }
        )
        )

        }

        but I get a log error “Uncaught TypeError: a is undefined” where “a” seems to be the selectedText var.

        I fixed others error to get at this point, but this is a mysterious issue.
        Can you help me to find where I get wrong?

        Thank You

        1. Antonio Villegas Avatar

          You can try to debug the code using a console.log statement to print the value input parameter. Alternatively, share a GitHub link with a minimum example showing the code.

          1. supergiu Avatar
            supergiu

            I tried all my best 🙂

            There is the github repo: https://github.com/supergiulab/gutenberg-buttons

            Thank you

          2. Antonio Villegas Avatar

            Here you have the fix you should apply to you code: https://wordpress.stackexchange.com/a/378887/198147

            🙂

  7. Casey O Avatar
    Casey O

    I can’t wait to get this to work on Gutenberg in Drupal.

Leave a Reply

Your email address will not be published. Required fields are marked *

I have read and agree to the Nelio Software Privacy Policy

Your personal data will be located on SiteGround and will be treated by Nelio Software with the sole purpose of publishing this comment here. The legitimation is carried out through your express consent. Contact us to access, rectify, limit, or delete your data.