
This tutorial covers block previews using PHP.
A Block.json version of this tutorial is available from DLX Plugins.
Block previews are an elusive pain-point and something I found hard to search for. As a result, this tutorial will show you how to create block previews for your block. The goal is to have an image or some block content show up when hovering over your block when adding it.

Block Initialization
When initializing your block, you can pass it some custom attribute values that will render the block in the preview pane. It’s important to set a description and use an example object which will pass attributes to your block.
For example, I have a block called wppp/slide-title
that has several attributes to show off a slide title. What we’re essentially doing is short-circuiting the default attributes that are passed to our block. Here’s an example:
registerBlockType( 'wppp/slide-title', {
title: __( 'Slide Title', 'wp-presenter-pro' ), // Block title.
icon: <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M5 4v3h5.5v12h3V7H19V4z"/><path fill="none" d="M0 0h24v24H0V0z"/></svg>,
description: __( 'Use a slide title for your main title for the slide.', 'wp-presenter-pro' ),
category: 'wp-presenter-pro',
keywords: [
__( 'slide', 'wp-presenter-pro' ),
__( 'title', 'wp-presenter-pro' ),
],
edit: edit,
save() {return null },
example: {
attributes: {
backgroundColor: '#000000',
opacity: 0.8,
padding: 30,
textColor: '#FFFFFF',
radius: 10,
title: __( 'I am a slide title', 'wp-presenter-pro' ),
},
},
} );
Code language: JavaScript (javascript)
Notice the example object above. This will be the object we use to short-circuit the default attributes passed to our block. We can essentially initialize the block with attributes and have a real preview based on our passed attributes.
Here’s the resulting preview:

Here’s another example I used for using my blockquote block.
registerBlockType( 'wppp/blockquote', {
title: __( 'Blockquote', 'wp-presenter-pro' ), // Block title.
icon: <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M6 17h3l2-4V7H5v6h3zm8 0h3l2-4V7h-6v6h3z"/><path d="M0 0h24v24H0z" fill="none"/></svg>,
description: __( 'Add flashy blockquotes to your presentation.', 'wp-presenter-pro' ),
category: 'wp-presenter-pro',
keywords: [
__( 'slide', 'wp-presenter-pro' ),
__( 'blockquote', 'wp-presenter-pro' ),
],
edit: edit,
save() {return null },
example: {
attributes: {
backgroundType: 'gradient',
backgroundGradient: 'linear-gradient(-225deg, rgb(255, 5, 124) 0%, rgb(141, 11, 147) 50%, rgb(50, 21, 117) 100%)',
align: 'center',
quoteStyle: 'quotes',
paddingTop: 30,
paddingBottom: 30,
blockquoteAlign: 'center',
textColor: '#FFFFFF',
content: __( 'An inspiring quote...', 'wp-presenter-pro' ),
},
},
} );
Code language: JavaScript (javascript)
In the above examples, the attributes I pass are defaults for my blockquote block. I pass in some attributes and the blockquote gets initialized with my attributes and renders a block preview.

Rendering an Image Instead
Here’s a technique for rendering an image instead of a block preview. It’ll require you to add an attribute to your attributes and make use of wp_localize_script
to point to the correct image.
Let’s get started with a plugin called WP Plugin Info Card, which currently does not have any block previews and it would be problematical to initialize the block via attribute overrides.
In this example, I’m passing an attribute called preview
and setting it to true.
example: {
attributes: {
'preview' : true,
},
},
Code language: JavaScript (javascript)
I’ll then use wp_localize_script to provide an image path to my block. Note: the image must exist in your plugin. I’ve found a good resolution to strive for is 680×720. You can experiment with these until you’ve found a good-sized image to use as a block preview.
wp_localize_script(
'wp_plugin_info_card-cgb-block-js',
'wppic',
array(
'rest_url' => get_rest_url(),
'query_preview' => plugins_url( 'img/wp-query-preview.jpg', __FILE__ ),
'wppic_preview' => plugins_url( 'img/wp-pic-preview.jpg', __FILE__ ),
)
);
Code language: PHP (php)
In the above example, both files are in an img
folder and simply point to the URL path to the image.
We need to add the preview attribute to our block initialization, which I do using register_block_type
.
register_block_type(
'wp-plugin-info-card/wp-plugin-info-card',
array(
'attributes' => array(
/* More code here */
'custom' => array(
'type' => 'string',
'default' => '',
),
'width' => array(
'type' => 'string',
'default' => '',
),
'preview' => array(
'type' => 'boolean',
'default' => false,
),
),
'render_callback' => 'wppic_block_editor',
)
);
Code language: PHP (php)
Finally, we add it as a prop in our block and return an image if preview
is true.
render() {
const { attributes } = this.props;
const { image, containerid, margin, clear, expiration, ajax, scheme, layout, width, preview } = attributes;
Code language: JavaScript (javascript)
Here’s our preview markup, which (if true) returns an image preview.
if ( preview ) {
return(
<Fragment>
<img src={wppic.wppic_preview} />
</Fragment>
);
}
Code language: JavaScript (javascript)
And here’s the resulting preview:

Congratulations! You’re done!
Conclusion
In this tutorial, I demonstrated how to pass props to your block in order to generate a preview. I also demonstrated how to simply use an image for the block preview.
Please leave any comments if you have any further questions.
uNFORTUNATELY, i CANNOT GET THE PREVIEW TO WORK. iS THE RENDER FUNCTION SUPPOSED TO BE IN THE BLOCK CODE, WHILE THE OTHER FUNCTIONS ARE IN INIT.PHP?
Super helpful, thanks Ron!