Custom Post Type Archive URL takes over page URL

When you register your post type, set the has_archive argument to false. If you change it, don’t forget to flush your rewrite rules to see the change.

Now this works fine if, as you asked, you want to show the page and not the archive. What about the situation where you’d like to show the page’s content and also the listing of custom posts?

There are two approaches you can use to achieve this.

1 – Use a Page Template

This is the one I see most often around the web. Create a page template and after showing the title and content use a custom loop to show your posts. It does the job, but people seem to get messed up with proper pagination quite often.

2 – Page for Custom Posts

This is my preferred approach. I keep has_archive when I register my post type and I make a normal Page to use with the archive template. The Page’s slug matches the Archive slug. By default WP’s rewrite rules are ordered so that the Archive trumps the Page.

At the start of my archive-{post_type}.php template I place this:

$queried_object = get_queried_object();

$page_data = get_page_by_path( $queried_object->rewrite['slug'] );

/* no need to check our context, as we know that this 
   code will only run for our CPT archives
*/

if ( !is_single() ) {
    echo apply_filters('the_content', $page_data->post_content);
}

// process the content in the same way that the_content would within a loop

// Now go into your usual archive loop...

If you prefer you could use a page ID or even set up an option for your post type that’s equivalent to the built-in Page for Posts.

This way you aren’t having to reconstruct the more difficult archive query for yourself.

Leave a Comment