Site icon Hip-Hop Website Design and Development

WordPress sent multiple requests on update

I have a problem with hooks being fired multiple times when I press update on a post (page in this example)

I tried everything here:
Unable to prevent function using save_post firing twice

But since it looked like I was receiving multiple requests I started to examine the access log.

When I hit update these are the posts sent:

[ip_number] - - [26/Aug/2021:15:31:00 +0000] "POST /wp-json/wp/v2/pages/1373?_locale=user HTTP/2.0" 200 3805 "https://example.com/wp-admin/post.php?post=1373&action=edit" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36"
[ip_number] - - [26/Aug/2021:15:31:00 +0000] "POST /wp-admin/post.php?post=1373&action=edit&meta-box-loader=1&meta-box-loader-nonce=[nonce]&_locale=user HTTP/2.0" 302 0 "https://example.com/wp-admin/post.php?post=1373&action=edit" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36"

So I started to do some logging:

add_action("publish_page", "my_publish_page", 10, 2);
function my_publish_page($postId, $post) {
    error_log("Debug for my_publish_page");
    error_log("postId: " . $postId);
    error_log("GET: ". var_export($_GET, true));
}

And the log file showed:

[26-Aug-2021 15:41:59 UTC] Debug for my_publish_page
[26-Aug-2021 15:41:59 UTC] postId: 1373
[26-Aug-2021 15:41:59 UTC] GET: array (
  '_locale' => 'user',
)
[26-Aug-2021 15:41:59 UTC] Debug for my_publish_page
[26-Aug-2021 15:41:59 UTC] postId: 1373
[26-Aug-2021 15:41:59 UTC] GET: array (
  'post' => '1373',
  'action' => 'edit',
  'meta-box-loader' => '1',
  'meta-box-loader-nonce' => '[nonce]',
  '_locale' => 'user',
)

So, two requests are sent, both trigger the publish_page action hook (and save_post or whatever similar hook you prefer). Both have the publish status for the post and none of them is true for wp_is_post_autosave (or DOING_AUTOSAVE).

I could for example look at the $_GET variable and only trigger my code if, for example $_GET[‘post’] == $postId, but that seems a bit hacky. Why is this happening, and is there a clean solution to prevent this "double-firing"?