I cannot figure this out. There seems to be no checkbox or anything similar in function to add the newly created custom post type archive page into the menu.

Also the link must be active, if you are on the page. This probably isn't possible, but is there some plugin for it? For the love of me, I cannot find it :(

I only found this plugin called Custom Post Type Archives in Nav Menus, that doesn't really do anything, but add custom link to the menu..with the full site-url. It doesn't go active or isn't very dynamic.

I thought that, probably the easiest way would be to override wp_nav_menu() and add my links manually and then use $_GET information to control the "currently active link".


2 Answers 2


This is one method that I think should work (though it's not tested).

//Hook on to the filter for the (custom) main menu
// 'wp_list_pages' filter is a fallback, when a custom menu isn't being used 
add_filter( 'wp_list_pages', 'new_nav_menu_items' );
add_filter( 'wp_nav_menu_items', 'new_nav_menu_items' );
//Can also hook into a specific menu...
//add_filter( 'wp_nav_menu_{$menu->slug}_items', 'new_nav_menu_items' );

function new_nav_menu_items($items) {
    global $wp_query;
    $class ='';

    //Checks if we are viewing CPT 'myposttype', if so give it the 'active' class.
    if(isset($wp_query->query_vars['post_type'])&& $wp_query->query_vars['post_type']=='myposttype') 
        $class = 'current_page_item';

    //This generates the url of the CPT archive page
    $url = add_query_arg('post_type','myposttype',site_url());

    $myitem = '<li class="'.$class.'"><a href="'.$url.'">My Custom Post Type</a></li>';

    $items = $items . $myitem;
    return $items;

This doesn't seem to me, to be the cleanest of solution, but I don't know of any other way. If there is, I'd like to see it!

Finally, the link url the custom item links to is not 'pretty' - but you could make it so if you new the slug of the CPT (assuming custom permalinks are being used....)

  • Thank you for answering. This seems to basically work. However, the formatting of the URL needs some tweaking. And I was hoping maybe you know about WP more then I. So currently the url is: example.com/?post_type=myposttype but should be example.com/myposttype. Maybe simply $url = site_url() . 'myposttype';? And the classes are not being included, including the currently active one. Dec 5, 2011 at 18:11
  • Oh sorry, didn't see the $class = '';. However, cant I get the normal classes dynamically and also how to make the currently active link to work? Dec 5, 2011 at 18:15
  • Oh double sorry, Didn't see the $wp_query->query_vars['post_type']=='myposttype'. Works basically. This is a good basis for more dynamic solution for sure, thanks! Dec 5, 2011 at 18:18

As of WordPress 4.4 (December 2015), Custom Post Type archive links are now officially supported in WordPress core without any third-party code or plugins needed.

You can read the entire Trac #16075 ticket for a full discussion or the Make WordPress Core post for a summary of the additional labels.

To enable the new built-in support for archive menu links, custom post types have to registered with non-falsey (i.e. true) values for has_archive, publicly_queryable and show_in_nav_menus:

add_action( 'init', function () {
    register_post_type( 'movies',
            'labels' => array(
                'name' => __( 'Movies' ),
                'singular_name' => __( 'Movie' ),
                'archives' => __( 'Movies' ),
            'public' => true,
            'has_archive' => true,
            'rewrite' => array(
                'slug' => 'movies',

With these additions, you'll see a new metabox on the Appearance > Menus admin screen.

The post type archive link can be found under the 'View All' tab within the post type metabox:

WordPress Custom Post Type Archive Nav Menus Link

Note: You may need to toggle the "screen options" drawer and ensure that your "Post Type Archives" name (e.g. Movies) is checked in order for it appear on the Menus screen.


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.