I have 2 custom post types: software and hardware. For SEO reasons I would like to have the permalinks of single software and hardware pages like:

https://domain.com/custom-post-name/

But as default WordPress adds post-type slug on it like:

https://domain.com/post-type-slug/custom-post-name/

I’ve removed the slug with following script that makes a replacement of the string. Now the single page is reachable with both urls described above and Google search console find 2 pages with the exact same content which is not good for SEO.
Is it possible to change the complete structure of a permalink and get rid of custom post type slug?

register_post_type( 'hardware',
    array (
        'labels' => $labels,
        'has_archive' => true,
        'public' => true,
        'supports' => array( 'title', 'editor', 'excerpt', 'custom-fields', 'thumbnail' ),
        'taxonomies' => array( 'hardware-post_tag', 'hardware-category' ),
        'exclude_from_search' => false,
        'capability_type' => 'post',
        'rewrite' => array( 'slug' => 'hardware' ),
    )
);

4 Answers
4

Note one Important thing to the above answer:

While it’ll work fine from the first sight it will cause performance problems.
All this code will be called on init hook so every page load will cause it to run and flush_rules() is very time expensive.

So it’s recomended to call flush rules upon theme\plugin activation only. Also you can use add_permastruct functions without need to access global $wp_rewrite

Final improved solution would be:

add_action('init', 'my_custom_rewrite'); 
function my_custom_rewrite() {

    add_permastruct('hardware', '/%customname%/', false);
    add_permastruct('produkt', '/%customname%/', false);
}

add_filter( 'post_type_link', 'my_custom_permalinks', 10, 2 );
function my_custom_permalinks( $permalink, $post ) {
      return str_replace( '%customname%/', $post->post_name, $permalink );
}

 /* in case for plugin */
register_activation_hook(__FILE__,'my_custom_plugin_activate');
function my_custom_plugin_activate() {
    flush_rewrite_rules();
}


/* in case of custom Theme in Functions.php */
add_action('after_switch_theme', 'mytheme_setup');
function mytheme_setup () {
    flush_rewrite_rules();
}

Leave a Reply

Your email address will not be published. Required fields are marked *