Rename class names in Gutenberg blocks

How to get rid of the default class names in Gutenberg blocks on the frontend? You know, those ones who started with .wp-block-whatever.
In this post, we find out how to rename the class names from those blocks and from the elements inside them.

In my previous post Gutenberg blocks: Add custom default class names, we saw how to give standard Gutenberg blocks their own classes when there is no class at all. For example, a <p> or <ul> tag has no class name by default.

For now we focus on blocks which already have their own class names by default. These blocks have al in common that the class names are all starting with wp-block.

So what we want is changing or rename the class names on the frontend from .wp-block-whatever to .some-totally-different.

As example blocks, we use the image and quote blocks. I choose these blocks with a particular reason. Both blocks have nested elements, so we take also a look at how to change/add classes on these ones.

But first things first. Let’s create an image and quote inside a new post.

In our example, we are working with the Twenty Nineteen Theme, and at this time of writing, we have installed WordPress version 5.2.3. For inspecting the elements in the browser, we use Chrome (version 76).

Image and quote created with Gutenberg blocks

After saving the post, we inspect the rendered HTML on the frontend.

Inspect element in chrome of image and quote with default class names.

Before we go further

I assume that you know how to implement the JavaScript snippets you find below. If not, go to create-guten-block for a super quick start in making your own Gutenberg blocks plugin.

Rename the wp-block classes

To rename class names started with wp-block, we are using the filter blocks.getBlockDefaultClassName. This filter is according to the handbook, precisely made for what we want. Well, not entirely in this case. But let’s give it a shot.

For each block, we rename/overwrite the default class name.
It’s, of course totally up to you how you want to call them.

const setClassToBlockWithDefaultClassName = (className, blockName) => {
    if (blockName === 'core/quote') {
        return 'post__quote';
    }

    if (blockName === 'core/image') {
        return 'post__figure';
    }
    
    return className;
};

wp.hooks.addFilter(
    'blocks.getBlockDefaultClassName',
    'your-namespace/block-filters',
    setClassToBlockWithDefaultClassName
);

Lets take a look in WordPress.

Image block message: contains unexpected or invalid content

Ok, there is something to resolve. We start with the image and click on the grey resolve button.

wp-block-image still visible on resolve screen
wp-block-image..? huh?

Seems like wp-block-image is still there. And that is not what we want. So, what can we do? Well, I give you two options.

First, you can delete the changed blocks and create new ones. This is because, for new blocks, the filter did the job right. And good to know when you start a new project.

The second option (or next step), fixed our problem by using the blocks.getSaveContent.extraProps filter.

const fixForRenamedBlockClassNames = (props, blockType, attributes) => {
    if (blockType.name === 'core/image') {
        if (props.className.includes('wp-block-image')) {
            props.className = props.className.replace('wp-block-image', '');
        }
    }

    if (blockType.name === 'core/quote') {
        if (props.className.includes('wp-block-quote')) {
            props.className = props.className.replace('wp-block-quote', '');
        }
    }

    return props;
};

wp.hooks.addFilter(
    'blocks.getSaveContent.extraProps',
    'your-namespace/block-filters',
    fixForRenamedBlockClassNames
);
wp-block-image is correctly replaced.
So, that’s better.

When inspecting in Chrome, we can see the correct and renamed class names.

Image and quote have renamed class names when inspecting elements.

So, let’s take a look now at the nested elements.

Add class names to nested elements

Notice when we look at the nested elements, most of them have no class attribute at all. For that reason, we simply create them.

Before I explain how and why. Below all the code we use. Again, we use also the filter blocks.getSaveContent.extraProps.

const coreImageBlock = props => {
    if (typeof props.children.props === 'undefined') {
        return props;
    }

    const children = props.children.props.children;

    if (children[0]) {
        Object.assign(children[0].props, {
            className: `post__image ${children[0].props.className}`,
        });
    }

    if (children[1]) {
        Object.assign(children[1].props, {
            className: 'post__figcaption',
        });
    }

    return props;
}

const coreQuoteBlock = props => {
    const children = props.children;

    if (children[0]) {
        const message = children[0];

        message.props.value = message.props.value.replace(/<p>/gi, '<p class="post__quote__text">')
    }

    if (children[1]) {
        Object.assign(children[1].props, {
            className: 'post__quote__cite',
        });
    }

    return props;
}

const classNamesForNestedElements = (props, blockType) => {
    if (blockType.name === 'core/image') {
        coreImageBlock(props);
    }

    if (blockType.name === 'core/quote') {
        coreQuoteBlock(props);
    }

    return props;
};

wp.hooks.addFilter(
    'blocks.getSaveContent.extraProps',
    'your-namespace/block-filters',
    classNamesForNestedElements
);

The image element has, in this case, the class name wp-image-805. Because WordPress use a number (image id) at the end of the class name for building the correct srcset attribute, it is not handy to rename this class completely. Therefore we keep this class beside a new one.

While there are elements with no class names at all, we can just assign them.

Further, attention for line 29. Because WordPress uses <p> tags inline for wrapping the value, we have to choose another solution. By replacing the first <p> tag entirely for a new one with a class name.

message.props.value = message.props.value.replace(/<p>/gi, '<p class="post__quote__text">')

After reloading the page in WordPress, we can resolve the warnings and update the page.

Warning

It is possible there is no editor warning. By just making a change somewhere on the page and update could also work.

You can always check the console if there is a block validation active.

Finally, we can check the results when inspecting the elements in the browser.

You can check here the source code.

That’s it. If there are questions, you can always send an email.