Add Images To Block Plugins In WordPress
Learn how to add images to block plugins created for WordPress to customize elements for your site enhancing the UI.

In this post I will show you an example of how to add images to block plugins in WordPress.

Adding Images To WordPress Block Plugin

Adding images to your WordPress site will make the site more attractive and inviting to users. For me, some of the existing plugins are great but I would like to add a personal touch. Building a block plugin is a bit easier than it seems. The various files needed to edit could be intimidating but after following a few guides, you will be able to create a personalized plugin too.

After following this example, all you would need to do is provide element styling to match your specific needs.

You can follow the post below to help provide information on adding WordPress block plugin attributes as CSS style variables.

Use WordPress Block Attributes As CSS Variables

I would also like to give credit to another author that helped me understand a few different aspects while developing this.

WordPress Gutenberg add image select custom block

Notes

In order to add images to block plugins, we will need to provide a way to access the media library built into WordPress. We will utilize the MediaUpload to do this. Along with MediaUpload, we will import MediaUploadCheckΒ . MediaUploadCheck is a library that will validate the users access to the media library.

The created attribute in the block.jsonΒ  file will be of type object. The image attributes that we will save for this example are the ID and the URL from the selected image to the attribute object. More information can be nested inside the attribute as necessary for your use case such as alt text.

In this example I have provided a stylesheet used to style the editor settings as well as a seperate stylesheet for the frontend.

For rendering the frontend UI, I am using dynamic rendering but this could be ported for static as well.

Code

Block.json

The only parameters edited in this file are the attribute and render. We added a single attribute named img with the type of object. The frontend will be dynamically created with a file named render.php. We specified this file at the bottom of the file under the parameter render.

{
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 3,
	"name": "r2creations24/my-custom-blocks-image",
	"version": "0.1.0",
	"title": "My Custom Blocks Image",
	"category": "widgets",
	"icon": "smiley",
	"description": "Custom blocks created by R2creations24.",
	"example": {},
	"attributes": {
		"img": {
	        "type": "object"
		}
	},
	"supports": {
		"html": false
	},
	"textdomain": "my-custom-blocks-image",
	"editorScript": "file:./index.js",
	"editorStyle": "file:./index.css",
	"render": "file:./render.php",
	"style": "file:./style-index.css",
	"viewScript": "file:./view.js"
}

Save.js

This file is for static rendering. Static rendering can easily done with this sample project by creating the same UI created in the edit.jsΒ here. I only created this example with dynamic rendering. We just need to return null.

export default function save() {
	return null;
}

Edit.js

This is where all the work is done to create the settings UI as well as the UI for the editor on the post or page this block plugin will be used on.

Breakdown

There are a few items to talk about here. I have a few libraries that are imported into the project. Also the implementation of the DOM element styling.

ResponsiveWrapper

This library is imported to show a preview of the image in the right settings pane of the block plugin.

MediaUpload

We utilize the MediaUploadΒ library often in this file. The MediaUpload library has a built in function named render to open the media library for us when the user clicks the ButtonΒ element we create inside it. We just need to capture the image they chose and save it to the attribute. Preview a sample of the MediaUpload below.

<MediaUpload
      onSelect={ onSelectedImage } // get the image data and send to function to process
      type="image"
      value={attributes.img} // attribute set in block.json
      render={({ open }) => ( // built in function to open the media library
          attributes.img === undefined && // validate img attribute is not set
                <div class="img_pick_btn">
                      <button onClick={open}>
                            Pick an Image
                      </button>
                  </div>
            )}
/>

As mentioned before, I created multiple MediaUpload buttons. This is for a better user experience. The example of the button above will only show is the img attribute has not been set. Another MediaUploadΒ is used to replace the image if the user wants to change it. Finally, the last one is used to delete the image saved in the imgΒ attribute.

Element Styling

You may have also noticed I gave the DIVΒ element a class name. This will be used to style the UI in the editor settings pane for the block plugin via CSS.

import { __ } from '@wordpress/i18n';

import { 
	useBlockProps,
	InspectorControls,
    MediaUploadCheck,
    MediaUpload
 		} from '@wordpress/block-editor';

import { 
    ResponsiveWrapper 
        } from '@wordpress/components';

import './editor.scss';

export default function Edit( { attributes, setAttributes } ) {

    const blockProps = useBlockProps();

    const onSelectedImage = (media) => { 
        setAttributes({ img: {url:media.url,id:media.id} }); 
    }

	return (
		<>
    
    //editor return 
    
		</>
	);
}

Editor Return

		    <InspectorControls>
                <MediaUploadCheck>
                    <MediaUpload
                        onSelect={ onSelectedImage }
                        type="image"
                        value={attributes.img}
                        render={({ open }) => ( 
                            attributes.img === undefined &&
                            <div class="img_pick_btn">
                                <button onClick={open}>
                                    Pick an Image
                                </button>
                            </div>
                        )}
                    />
                    { attributes.img !== undefined && 
                        <MediaUploadCheck>
                            {attributes.img.url.length !== 0 && 
                            <div class="img_btn_panel">
                                <ResponsiveWrapper>
									    <img src={attributes.img.url} />
								</ResponsiveWrapper>
                                <div class="img_pick_btn">
                                <MediaUpload
                                    onSelect={ onSelectedImage }
                                    type="image"
                                    value={attributes.img}
                                    render={({ open }) => ( 
                                        attributes.img.url.length !== 0 &&    
                                            <button onClick={open}>
                                                Replace Image
                                            </button>
                                            )
                                        }
                                />
                            
                                    <button onClick={() => setAttributes({ img: undefined })} >
                                                Remove Image
                                    </button>
                                    </div>
                                </div>
                           }
                    </MediaUploadCheck>
                }
                </MediaUploadCheck>
            </InspectorControls>
		<div { ...blockProps }>
            <p>
			{ __(
				'This means nothing here, render.php changes static text.',
				'my-custom-blocks'
			) }
		</p>
        {attributes.img != undefined && 
        <img src={attributes.img.url}/>}
        </div>

Render.php

Creating the frontend UI via dynamic rendering in WordPress. This file is simple.

<div <?php echo get_block_wrapper_attributes(); ?>>
<p>
    Hello from Render.PHP.....excited?!?
</p>
<img src="<?php echo $attributes['img']['url']; ?>" />
</div>

Editor.scss

Stylesheet for the UI in the editor.

.wp-block-r2creations24-my-custom-blocks-image {
	border: 1px dotted #f00;
}

.components-responsive-wrapper {
	padding: 15px;
}

.components-responsive-wrapper__content {
	width: 50%;
	margin: auto;
	background-color: aliceblue;
}

.img_pick_btn {
	width: 100%;
    display: inline-flex;
    margin: auto;
    justify-content: space-evenly;
    margin: auto;
    padding: 5px;
}

.img_btn_panel:has(button:hover) {
	background-color: rgba(102, 102, 102, 0.233);
}

Style.scss

Stylesheet for the UI in the editor.

.wp-block-r2creations24-my-custom-blocks-image {
	background-color: #219b8b;
	color: #fff;
	padding: 2px;
    display: flex;
    align-items: center;
}

.wp-block-r2creations24-my-custom-blocks-image img {
	width: 50%;
    margin: auto;
}

Hope this was useful.