I have a plugin that implements a REST API that needs to be notified when an admin adds one of my supported shortcodes to a page or post. I hook save_post with my function like this.

        add_action( 'save_post', 'detect_shortcodes');

However, when I update from the editor, it does an ajax call that instantiates my plugin. The first thing it does is determine whether to load public or admin hooks like this.


Of course, my detect_shortcodes function is on the admin side. With the TinyMCE editor, this worked correctly, and instantiated my admin hooks. With the Gutenberg editor, is_admin() returns false.

Is there a replacement for is_admin() that will work with Gutenberg ajax calls?

  • So your remote request works when it runs, but it never attempts it? Or does the remote request run but it fails? That it's running a frontend partial is unexpected, the REST API returns JSON, if your code is breaking that then it won't be able to work as expected. I notice that your save post hook is incomplete? Can you expand your code snippet so that it shows the entire hook and how it's being added? If the reply wasn't a valid JSON response then what was the reply? You can check this in the network tab with browser tools
    – Tom J Nowell
    Mar 8, 2020 at 21:08
  • With block editor, the detect_shortcodes callback doesn't fire. With Classic editor, it fires and completes both REST calls. It is returning the entire contents of the event.php partial, followed by this json, which looks like what it is expecting: {"id":87,"date":"2020-03-07T14:52:00","date_gmt":"2020-03-07T14:52:00","guid"... It chokes on this before it fires detect_shortcodes and returns with the Invalid JSON error. So you're asking for the complete detect_shordcodes source? It's long...
    – AldenG
    Mar 8, 2020 at 21:23
  • So I don't believe the partial is related to this problem, though I agree it is a problem, it's its own separate problem. These are 2 issues, not 1. If your theory is correct, then you need to figure out why that partial is being displayed, which is not possible to diagnose given the information in this question. But it shows the correct response in JSON, so that is not the cause. These are 2 separate individual issues, focus on figuring out why the partial is rendering before returning to this one first
    – Tom J Nowell
    Mar 8, 2020 at 21:44
  • This is POST that the block editor is doing that is causing the trouble. wp-ea.azurewebsites.net/wp-json/wp/v2/pages/87?_locale=user You'll see my event.php partial in there, which is actually a Vue template. That is the expanded content of the shortcode. At the bottom is the json it wants. Any idea how this can happen?
    – AldenG
    Mar 8, 2020 at 22:00
  • I've isolated the issue to this: wordpress.org/support/topic/is_admin-not-working. This is why the public side is loading. However, the thread doesn't provide an answer. I'll update the topic and hope we can get an answer, here.
    – AldenG
    Mar 9, 2020 at 0:14

3 Answers 3


You could try with the following instead to detect if rest

if ( is_admin() || defined( 'REST_REQUEST' ) && REST_REQUEST ) {


I think this hook should work:

function run_hooks( $post, $request ) {
    // Here you can run your hooks
add_action('rest_after_insert_post', 'run_hooks', 10, 2);
  • Please edit your answer, and add an explanation: why could that solve the problem?
    – fuxia
    Mar 9, 2020 at 8:54
  • The larger issue here is that the REST save request is forcing me to load the entire public side of my plugin while on the admin side by returning false from is_admin(). I need a way of detecting this save, so I instantiate my admin hooks, one of which is on save_post.
    – AldenG
    Mar 9, 2020 at 15:18

I have landed on this embarrassing hack. I hope someone can improve this answer and make it less brittle. Perhaps read taxonomy to find current pages and posts endpoints?

    $pagesajax = 'wp-json/wp/v2/pages';
    $postsajax = 'wp-json/wp/v2/posts';

    if(is_admin() || !empty($_SERVER['REQUEST_URI']) &&
        strpos($_SERVER['REQUEST_URI'], $pagesajax) !== false ||
        strpos($_SERVER['REQUEST_URI'], $postsajax) !== false)
        ... load admin side ...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.