How to Change WordPress Post Slugs to Include Blog/Category

Including the blog/category in post slugs offers valuable benefits for both users and SEO. By incorporating this information into URLs, your website becomes more organized and navigable, as users can quickly understand the context of the content and explore related topics with ease. Moreover, it improves SEO by creating keyword-rich URLs that help search engines better understand and index your content, potentially leading to higher rankings.

1. Add blog/category to the permalink structure

After verifying the post_type and the post_status, generate the new permalink using the post_link filter.

function youbou_change_post_permalink( $permalink, $post, $leavename ) {

    if ( 'post' != $post->post_type || 'publish' != $post->post_status ) {
        return $permalink;
    }

    $categories = get_the_category( $post->ID );
    $category   = $categories[0]->slug;
    $permalink  = home_url( '/blog/' . $category . '/' . $post->post_name . '/' );

    return $permalink;
}
add_filter( 'post_link', 'youbou_change_post_permalink', 10, 3 );

2. Custom rewrite rules

If you have /blog/ in the slug of your blog page, you need to add the first rule to prevent a 404 error page when navigating to pages beyond the first page.

function youbou_rewrite_rules() {
    add_rewrite_rule( '^blog/page/([0-9]{1,})/?$', 'index.php?pagename=blog&paged=$matches[1]', 'top' );
    add_rewrite_rule( '^blog/([^/]+)/([^/]+)/?', 'index.php?name=$matches[2]', 'top' );
}
add_action( 'init', 'youbou_rewrite_rules' );

3. Redirecting old post links to new structure

This function is hooked to the template_redirect action, ensuring it runs before the template is displayed to the user.

function youbou_redirect_old_post_link() {

    if ( ! is_single() ) {
        return;
    }

    global $post;

    $categories = get_the_category( $post->ID );

    if ( empty( $categories ) || ! is_array( $categories ) ) {
        return;
    }

    $category  = $categories[0]->slug;
    $permalink = home_url( '/blog/' . $category . '/' . $post->post_name . '/' );
    $url       = site_url( $_SERVER['REQUEST_URI'] ?? '' );

    if ( $url !== $permalink ) {
        wp_redirect( $permalink, 301 );
        exit;
    }
}
add_action( 'template_redirect', 'youbou_redirect_old_post_link' );
#