Posts Permalink: Force Rewrite WordPress URLs to Use /blog/ in Posts Permalink Structure

This tutorial will show you ways to force rewrite WordPress URLs to use /blog/ in posts permalink structure. Websites that have an outsized number of pages, custom post types, posts, and posts categories may benefit by using the prefix “blog” within the URL rather than the blog category name slug. Most importantly, blogs that have posts in multiple categories, or categories that get removed or changed, should use this type of URL structure.

For example, if a website’s blog has URLs that look like the following:

The category slug name is replaced with “blog” and the URLs are rewritten to look like the following:

Posts Permalink Structure for SEO

It is recommended by Yoast SEO to use the category and therefore the post name slug within the URL for the right WordPress SEO permalink structure. This can be accomplished by editing the permalinks within the WordPress admin area. There are variety of tags available to use. For the sake of this tutorial, use the subsequent format:


To start, go to the Permalinks Settings page in the WordPress admin:

Settings > Permalinks

Next, add the tags into the custom structure field:

The above settings will output the category name and the post name in the permalink. The URLs will look like the following:

WordPress does not offer a simple mechanism or option to rewrite only the posts permalink structure. Editing the above Custom Structure field to force “/blog/%postname%” is an incomplete solution.

Replace Category Names with /blog/ in Posts Permalink Structure

The first a part of the answer to adding the /blog/ prefix to the post URLs is to use the post_link WordPress filter to only modify the posts. the following step is to rewrite the URLs that include “blog/” by hooking into the generate_rewrite_rules WordPress function. The category name are going to be stripped from the posts permalink structure and get replaced with “blog”. Each posts attachment, embed, trackback, feed, page, and comments URL also will be rewritten to properly resolve to the new post URL.

Your website’s paginated pages might not display correctly when creating a page with “blog” because the slug and using pagination. However, the primary rewrite rule below solves this issue in order that WordPress finds following page before trying to seek out the only post.

Paste the following code snippet into the functions.php file of your active parent theme or child theme.

function wp_pro_blog_generate_rewrite_rules( $wp_rewrite ) {
  $new_rules = array(
    '(([^/]+/)*blog)/page/?([0-9]{1,})/?$' => 'index.php?pagename=$matches[1]&paged=$matches[3]',
    'blog/([^/]+)/?$' => 'index.php?post_type=post&name=$matches[1]',
    'blog/[^/]+/attachment/([^/]+)/?$' => 'index.php?post_type=post&attachment=$matches[1]',
    'blog/[^/]+/attachment/([^/]+)/trackback/?$' => 'index.php?post_type=post&attachment=$matches[1]&tb=1',
    'blog/[^/]+/attachment/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$' => 'index.php?post_type=post&attachment=$matches[1]&feed=$matches[2]',
    'blog/[^/]+/attachment/([^/]+)/(feed|rdf|rss|rss2|atom)/?$' => 'index.php?post_type=post&attachment=$matches[1]&feed=$matches[2]',
    'blog/[^/]+/attachment/([^/]+)/comment-page-([0-9]{1,})/?$' => 'index.php?post_type=post&attachment=$matches[1]&cpage=$matches[2]',		
    'blog/[^/]+/attachment/([^/]+)/embed/?$' => 'index.php?post_type=post&attachment=$matches[1]&embed=true',
    'blog/[^/]+/embed/([^/]+)/?$' => 'index.php?post_type=post&attachment=$matches[1]&embed=true',
    'blog/([^/]+)/embed/?$' => 'index.php?post_type=post&name=$matches[1]&embed=true',
    'blog/[^/]+/([^/]+)/embed/?$' => 'index.php?post_type=post&attachment=$matches[1]&embed=true',
    'blog/([^/]+)/trackback/?$' => 'index.php?post_type=post&name=$matches[1]&tb=1',
    'blog/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$' => 'index.php?post_type=post&name=$matches[1]&feed=$matches[2]',
    'blog/([^/]+)/(feed|rdf|rss|rss2|atom)/?$' => 'index.php?post_type=post&name=$matches[1]&feed=$matches[2]',
    'blog/page/([0-9]{1,})/?$' => 'index.php?post_type=post&paged=$matches[1]',
    'blog/[^/]+/page/?([0-9]{1,})/?$' => 'index.php?post_type=post&name=$matches[1]&paged=$matches[2]',
    'blog/([^/]+)/page/?([0-9]{1,})/?$' => 'index.php?post_type=post&name=$matches[1]&paged=$matches[2]',
    'blog/([^/]+)/comment-page-([0-9]{1,})/?$' => 'index.php?post_type=post&name=$matches[1]&cpage=$matches[2]',
    'blog/([^/]+)(/[0-9]+)?/?$' => 'index.php?post_type=post&name=$matches[1]&page=$matches[2]',
    'blog/[^/]+/([^/]+)/?$' => 'index.php?post_type=post&attachment=$matches[1]',
    'blog/[^/]+/([^/]+)/trackback/?$' => 'index.php?post_type=post&attachment=$matches[1]&tb=1',
    'blog/[^/]+/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$' => 'index.php?post_type=post&attachment=$matches[1]&feed=$matches[2]',
    'blog/[^/]+/([^/]+)/(feed|rdf|rss|rss2|atom)/?$' => 'index.php?post_type=post&attachment=$matches[1]&feed=$matches[2]',
    'blog/[^/]+/([^/]+)/comment-page-([0-9]{1,})/?$' => 'index.php?post_type=post&attachment=$matches[1]&cpage=$matches[2]',
  $wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
add_action( 'generate_rewrite_rules', 'wp_pro_blog_generate_rewrite_rules' );

function wp_pro_update_post_link( $post_link, $id = 0 ) {
  $post = get_post( $id );
  if( is_object( $post ) && $post->post_type == 'post' ) {
    return home_url( '/blog/' . $post->post_name );
  return $post_link;
add_filter( 'post_link', 'wp_pro_update_post_link', 1, 3 );

Final Thoughts

Use the Rewrite Rules Inspector plugin to check that WordPress is correctly using the updated rewrite rules.

Make sure to flush your rewrite rules after inserting the above code snippet in the functions.php file. Save the permalinks a couple of times in the WordPress admin area:

Settings > Permalinks

Need help? Our WordPress Development Service is a comprehensive solution for small, medium and enterprise-level businesses. Email us at for a free consultation.

Pin It on Pinterest

Share This