Creating Custom Notices in Block Editor (Gutenberg)
Recently I’ve been working with my Simple WP Crossposting plugin and I found out that in order to make the experience with the plugin even more simple I need to add some custom notices for users.
Adding those notices in Classic Editor is super simple – we just need to use admin_notices
hook and there we go. But in Gutenberg things may become just a little bit more complicated.
Anyway we are going to figure everything out in this tutorial.
Creating a Simple Notice
Let’s start with something not very complicated. For example right now I am going to create a notice like this:

Displaying a notice like that is actually as easy as running the code below:
wp.data.dispatch( 'core/notices' ).createNotice(
'warning',
'Hey, how is it going?',
{
id: 'misha-greetings-notice',
isDismissible: true,
}
);
In this code please keep in mind that:
- There are different notice types, we’ve created a
warning
type (yellow), but there are alsoerror
(red) andsuccess
(green) types. - You can also see that the notice can be dismissable or not with the help of parameter
isDismissible
. - It is also possible to use
type: 'snackbar'
if you want your notice to look like this:

type: 'snackbar',
}
);
More parameters you can find in the official documentation.
Validation Notices (Check if Featured Image is Set)
You can also create custom validation notices to check almost everything in the post, for example you can check whether the title is provided or has a specific length.
But in this example we are just checking if post featured image is set.

And the code is below:
let isNoticeDisplayed = false;
wp.data.subscribe( () => {
const featuredImage = wp.data.select( 'core/editor' ).getEditedPostAttribute( 'featured_media' );
if( 0 === featuredImage ) {
if( ! isNoticeDisplayed ) {
isNoticeDisplayed = true;
wp.data.dispatch( 'core/editor' ).lockPostSaving( 'rudr-featured-img' );
wp.data.dispatch( 'core/notices' ).createNotice(
'error',
'Do not forget about a featured image for your post!',
{
id: 'rudr-featured-img',
isDismissible: false
}
);
}
} else if( isNoticeDisplayed ) {
// if there is a featured image but the notice is still displayed
isNoticeDisplayed = false;
wp.data.dispatch( 'core/editor' ).unlockPostSaving( 'rudr-featured-img' );
wp.data.dispatch( 'core/notices' ).removeNotice( 'rudr-featured-img' );
}
} );
Some code explanation:
- In this code we are using
wp.data.subscribe()
so we can check whether a featured image is set or not in real time. isNoticeDisplayed
variable is required to prevent the code running a lot of times and it also helps you with an error “Uncaught RangeError: Maximum call stack size exceeded”.- We’re also blocking “Update” and “Publish” buttons when featured image is not set.
Displaying a Custom Notice Depending on a REST API Response
And this is actually the reason why I decided to publish a tutorial like that. In my Simple WP Crossposting plugin I needed to find a way to tell users when the connection to a sub-site is interrupted (for example an application password is removed).

1. Store REST API errors in post meta
This is the step when the potential errors may occur. Let’s assume that we are using save_post
action hook to sending a REST API request inside it, and if this request fails, we have to display a notice.
add_action( 'save_post', 'rudr_request_to_rest_api' );
function rudr_request_to_rest_api( $post_id ) {
$res = wp_remote_request( ... );
if( is_wp_error( $res ) ) {
update_post_meta(
$post_id,
'last_error',
wp_json_encode(
array(
'code' => $res->get_error_code(),
'message' => $res->get_error_message(),
)
)
);
}
}
This example is simplified and not necessary a HTTP API request should produce a WP_Error
object, but it is just a demonstration. By the way, if you think there is a better way to handle errors like this, please let me know in the comments section.
2. Creating a custom REST API endpoint
The whole idea is that just after we’ve saved a post in Gutenberg an additional REST API request will be sent to check if there were any errors or not. It means that we need to register an additional REST API endpoint for that purpose.
It can be done quite easily with the register_rest_route()
function.
add_action( 'rest_api_init', 'rudr_register_rest_api_route' );
function rudr_register_rest_api_route() {
register_rest_route(
'rudr/v1', // first part of the endpoint
'latest-error', // second part of the endpoint
array(
'methods' => WP_REST_Server::READABLE, // GET
'callback' => function( $request ) {
$post_id = $request->get_param( 'id' );
$last_error = get_post_meta( $post_id, 'last_error', true );
if( $last_error ) {
$last_error = json_decode( $last_error );
return new WP_REST_Response(
array(
'code' => $last_error->code,
'message' => wp_unslash( $last_error->message ),
)
);
} else {
return new WP_REST_Response( array( 'code' => 'OK' ) );
}
},
'permission_callback' => function() {
return current_user_can( 'edit_posts' );
},
)
);
}
Everything should be clear here, if it is not, I recommend to check register_rest_route()
function documentation.
Just one thing – you can see that on line 27
that I am returning a kind of empty WP_REST_Response
object, it is required because we always have to return a correct response, otherwise you are going to get some errors in your browser console.
3. Displaying the error when saving a post in Block Editor
And finally the last step, some JavaScript code to make it work in the Block Editor.
( function( wp ) {
const { subscribe, select, dispatch } = wp.data;
const { isSavingPost, getCurrentPostId } = select( 'core/editor' );
const { addQueryArgs } = wp.url;
let checked = true;
subscribe( () => {
if( isSavingPost() ) {
checked = false;
} else {
if ( ! checked ) {
checked = true;
// some variables
const postId = getCurrentPostId();
const path = addQueryArgs( '/swc/v1/latest-error', { id: postId } );
wp.apiFetch({
path: path,
}).then( function( response ){
if( response.message ){
dispatch( 'core/notices' ).createNotice(
'warning',
response.message,
{
id: 'rudr_notice',
isDismissible: true
}
);
} else {
dispatch( 'core/notices' ).removeNotice( 'rudr_notice' );
}
} );
}
}
} );
} )( window.wp );
This piece of code is kind of similar to what we did when created validation notices but with wp.apiFetch()
call.

Misha Rudrastyh
Hey guys and welcome to my website. For more than 10 years I've been doing my best to share with you some superb WordPress guides and tips for free.
Need some developer help? Contact me