Yoast SEO focus keyword field won't change via code

Hey everyone, I’m having trouble with my WordPress site. I’m trying to change the focus keyword in Yoast SEO using PHP code but it’s not working. When I run my code, nothing happens and the keyword stays the same in the backend.

I’ve been stuck on this for a while now. Has anyone else had this problem before? Here’s what I’m currently using:

$result = update_post_meta($article_id, '_yoast_wpseo_focuskw', $new_keyword);

I thought this would work but maybe I’m missing something. Any ideas what could be going wrong?

This happens because Yoast caches metadata internally and your direct database update skips their validation. Use WPSEO_Meta::set_value('focuskw', $new_keyword, $article_id) instead of raw update_post_meta. I hit this same issue when bulk updating keywords for a client’s product pages. The Yoast method handles their internal processes properly and updates the indexables table automatically. If you need to stick with update_post_meta, flush Yoast’s object cache afterward with wp_cache_delete($article_id, 'post_meta'). Also make sure your code runs after Yoast loads by hooking it to ‘plugins_loaded’ with priority 20 or higher.

Had the same issue a few months back on a client’s WordPress site. Your meta key’s right, but you’re probably missing one thing: Yoast’s internal cache needs clearing after the update. Add delete_transient('wpseo_sitemap_cache_validator'); right after your update_post_meta call. Make sure you’re running this code with admin privileges - sometimes updates won’t stick if Yoast’s indexables don’t refresh. Try calling WPSEO_Meta::get_value('focuskw', $article_id) right after your update to force Yoast to recognize the change. Also double-check that your $article_id is valid and actually exists - saves you from going down debugging rabbit holes.

Had the same issue. Yoast doesn’t always update the indexables table when you use update_post_meta. Add do_action('wpseo_save_compare_data', $article_id); right after your meta update. Also check you’re using the right hook - mine only worked when I put it in init or admin_init.