I'm trying to set a meta property to a new post's permalink using update_post_meta. When I run this on wp_after_insert_post I get a permalink that ends in "?p=[ID]". If I update the post to run the function again the permalink is updated to something that ends in, "/[category]/[post-name-slug]/" which is what I want to insert originally.

How can I delay update_post_meta until the permalink is resolved? I was thinking of using add_action/do_action to delay when I call update_post_meta but I'm using the post ID to get the permalink in the function. Any recommendations?

Here's my current code:

add_action('wp_after_insert_post', 'add_permalink_to_new_post', 0, 4);

function add_permalink_to_new_post( $post_id, $post, $update, $post_before ) {

    // Only run this on a newly created post
    if (!empty($post_before)) {
    update_post_meta( $post_id, 'canonical_permalink', (string) get_permalink($post_id) );

1 Answer 1


To execute update_post_meta after the permalink is customized, you can use the save_post hook instead of wp_after_insert_post. Here's how you can modify your code:

add_action('save_post', 'add_permalink_to_new_post', 10, 2);

function add_permalink_to_new_post($post_id, $post) {

    // Check if this is a new post
    if ($post->post_date_gmt == $post->post_modified_gmt) {
        // Only run this on a newly created post
        update_post_meta($post_id, 'canonical_permalink', get_permalink($post_id));

In the updated code:

  1. I've changed the hook to save_post, which fires after a post is saved or updated.
  2. Inside the add_permalink_to_new_post function, we check if the post_date_gmt and post_modified_gmt are the same. If they are, it means that the post is newly created, as the modification date hasn't been updated yet.
  3. If it's a newly created post, we update the canonical_permalink post meta with the customized permalink using get_permalink($post_id).

This way, the update_post_meta function will only be called after the permalink is customized for a newly created post, ensuring that you get the permalink you want without any issues with ?p=[ID]. You can now use this updated code in your WordPress theme or plugin to achieve the desired functionality.

  • Nice! I'm actually trying to update the Yoast canonical and unfortunately using save_post alone didn't do the trick. I had to use save_post to fetch the canonical and wp_after_insert_post to update the meta property. For some reason Yoast would overwrite the permalink with the ID version if I just used the save_post hook. Between both of those functions the code is working now. Thank you! Dec 27, 2023 at 21:16
  • Excellent! I'm glad this helped get you to a resolution 🤘 Dec 27, 2023 at 21:21

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.