Haven't found a useful answer for this. I am aware of the conflict issues and all the problems this may cause, I'm curious if it's POSSIBLE not SUGGESTED. This will require WP rewrites, I know this much.

Basically, let's say we have a CPT of "events". I want to have a single event's page have the URL http://domain.com/single-event-name and NOT http://domain.com/events/single-event-name. Any ideas on how to go about it?

  • Always wanted to find out about that, never thought of asking the question. Thanks!
    – fischi
    Dec 13, 2012 at 14:27
  • @robbennet in 2015 there still doesn't seem to be a legit way to do this with style. Sep 28, 2015 at 15:58

4 Answers 4


That's how you can do first part of the job - get rid o CPT slug in post link (eg. news post type).

function df_custom_post_type_link( $post_link, $id = 0 ) {  

    $post = get_post($id);  

    if ( is_wp_error($post) || 'news' != $post->post_type || empty($post->post_name) )  
        return $post_link;  

    return home_url(user_trailingslashit( "$post->post_name" ));  
add_filter( 'post_type_link', 'df_custom_post_type_link' , 10, 2 );

Now there should go a a rewrite rules for 'news', because you will get a 404 error.

Add the rewrite rule like this:

function df_custom_rewrite_rule() {
    add_rewrite_rule('(.*?)$', 'index.php?news=$matches[1]', 'top');
add_action('init', 'df_custom_rewrite_rule');

Then we'll need to flush rewrite rules, so go to Settings - Permalinks and save changes.

  • 1
    You shouldn't be adding rewrite rules on init. You should just add your rule to the current rules.
    – Chris_O
    Dec 19, 2012 at 6:36
  • 2
    @Chris_O Can you elaborate? How would one add the rule to the current rules?
    – Desi
    Jan 25, 2015 at 13:26
  • After adding this code, all of my pages having URLS as example.com/about-us stopped working ? Any solutions for this ? Dec 15, 2016 at 8:09

You can try this plugin( http://wordpress.org/extend/plugins/remove-slug-from-custom-post-type/ ) for removing the slug, but it will only work if the permalink structure is "/%postname%/

  • Exactly this plugin is awesome! I'm an experienced user of this plugin and I totally recommend it! here's the link of the plugin's site which explain it in depth ultimatewebtips.com/remove-slug-from-custom-post-type Dec 17, 2012 at 17:17
  • This is a nice Plugin, and has exactly the feature I was looking for. @bartosz solution is to one CPT specifically, although you too get the general idea from it. After digging into this Plugin it's all clear now, thank you!
    – fischi
    Dec 19, 2012 at 12:40
  • This plugin doesn't seem to be in the Wordpress repository anymore. However you can use this plugin instead.... https://wordpress.org/plugins/remove-cpt-base/
    – clayRay
    Nov 28, 2021 at 2:22
function register_cpt_type() {
    register_post_type('cpt', array(
        'rewrite' => array("slug" => "/cpt", "with_front" => false),
add_action('init', 'register_cpt_type')

function cpt_rewrite_rule() {
    add_rewrite_rule('(.*?)$', 'index.php?cpt=$matches[1]', 'top');
add_action('after_theme_setup', 'cpt_rewrite_rule');

flush/recycle url rewrites, then edit .htaccess

RewriteRule ^cpt/(.+)$ /$1 [R=301,L]

You could always hook into "parse_request" to perform a check to see if a custom type with the name requested exists and then modify the query_vars appropriately. You'll need something along the lines of @Bartosz's response to generate the permalink in addition:

 add_filter('parse_request', "t21_parse_request" , 1, 1);

 function t21_parse_request($wpobj)
      $query_vars = $wpobj->query_vars;
      $slug = $query_vars['pagename'];

      $posts = get_posts(array(
           "post_type" => "event",
           "post_name" => $slug

           //we know your "event" entry exists so we now amend the query_vars
           //first unset the 'page' and 'pagename'

           //now rebuild the query_vars
           $query_vars['post_type'] = "event"; //CPT name
           $query_vars['name'] = $slug;
           $query_vars['event'] = $slug; //again - this constructs the "event=myevent" query string
           //just return $wpobj since we know that there is no "event"
           return $wpobj;

This does assume however that you won't have any post names with the same name as a postname otherwise, the post will never appear as it matches with an event type first.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.