How do I use the same post slug for different Categories?

Using Parent-Child Page (Recommended)

If you don’t have to have categories & posts, then this can be easily achieved using parent-child pages (not posts).

For example, say you have three pages like:

www.example.com/category-one/
www.example.com/category-two/
www.example.com/category-three/

Now you can have child pages for the above pages with slug email, e.g.

www.example.com/category-one/email
www.example.com/category-two/email
www.example.com/category-three/email

This is possible because WordPress considers the entire parent-child combination slug for pages (or any other hierarchical post type) to be unique.

Of course, all these child pages with email slug are different pages, just with the same ending URL slug.

Using Category-Post combination

Warning: By default WordPress doesn’t support this & for good reason. May be now you have /%category%/%postname%/ as your current permalink structure, but what if it needs to be changed in the future? Then you’ll have conflicts.

Also, since WordPress doesn’t support this internally, you may have unforeseen issues with other plugins (e.g. custom permalink plugins, SEO plugins etc.).

This is possible using the wp_unique_post_slug filter hook. for example, the following sample Plugin will allow multiple occurrences of the email slug:

<?php
/*
Plugin Name:  WPSE non-unique post slug
Plugin URI:   https://wordpress.stackexchange.com/a/313422/110572
Description:  WPSE non-unique post slug
Version:      1.0.0
Author:       Fayaz Ahmed
Author URI:   https://www.fayazmiraz.com/
*/

add_filter( 'wp_unique_post_slug', 'wpse313422_non_unique_post_slug', 10, 6 );

function wpse313422_non_unique_post_slug( $slug, $post_ID, $post_status, $post_type, $post_parent, $original_slug ) {
    if( $post_type === 'post' && $original_slug === 'email' ) {
        // Perform category conflict, permalink structure
        //     and other necessary checks.
        // Don't just use it as it is.
        return $original_slug;
    }

    return $slug;
}

Leave a Comment