Work with content decay data to identify and refresh underperforming content.
The data comes from the Search Console part of the Pro add-on (the class RANKFORGE_GSC) and needs a connected property. A page is listed as decaying when its clicks in the last 28 days fell by more than 30% against the 28 days before, or when its average position got worse by more than 3 places. Each period holds up to 200 pages, and a page must be in both. In the data, click_change is the change in percent and position_change is above 0 when the position got worse.
Reading Cached Decay Data
// A Search Console load fills this cache (the daily job queues one)
$decay = get_option( 'rankforge_gsc_decay_cache', [] );
foreach ( $decay as $item ) {
printf(
"Post #%d (%s): clicks %d -> %d (%.0f%%), position %.1f -> %.1f\n",
$item['post_id'],
$item['title'],
$item['clicks_prev'],
$item['clicks_now'],
$item['click_change'],
$item['position_prev'],
$item['position_now']
);
}Flagging Decaying Content for Review
// Find decaying content and flag it for an editor
add_action( 'rankforge_daily_gsc_sync', function () {
if ( ! class_exists( 'RANKFORGE_GSC' ) || ! RANKFORGE_GSC::instance()->is_connected() ) {
return;
}
$decay = RANKFORGE_GSC::instance()->detect_content_decay();
foreach ( $decay as $item ) {
if ( $item['click_change'] < -50 && $item['post_id'] ) {
// Flag for editorial review via custom meta
update_post_meta( $item['post_id'], '_needs_content_refresh', '1' );
update_post_meta( $item['post_id'], '_decay_detected_at', current_time( 'mysql' ) );
}
}
}, 20 );Building a Decay Dashboard
// WP-Admin page listing all decaying posts
$flagged = get_posts( [
'post_type' => 'any',
'posts_per_page' => -1,
'meta_key' => '_needs_content_refresh',
'meta_value' => '1',
] );
foreach ( $flagged as $post ) {
$detected = get_post_meta( $post->ID, '_decay_detected_at', true );
echo esc_html( $post->post_title ) . " (flagged: {$detected})\n";
}—