Post type archive page not working

The question:

I registered a custom post type using Custom Post Type UI, and created an archive page and named it archive-recipe.php, ‘recipe’ is my custom post type name. But its not working, instead its using the default archive.php. I set the has-archive to true but still not working. How to fix that?

Here’s the code:

    'recipe', array(
'label' => 'Recipe',
    'description' => 'This is a Recipe Custom Post Type',
    'public' => true,
    'show_ui' => true,
    'show_in_menu' => true,
    'capability_type' => 'post',
    'hierarchical' => true,
    'rewrite' => array('slug' => ''),
    'query_var' => true,
    'has_archive' => true,
    'exclude_from_search' => false,
    'supports' => array('title','editor','excerpt','trackbacks','custom-fields','comments','revisions','thumbnail','author','page-attributes',),
    'labels' => array (
          'name' => 'Recipe',
          'singular_name' => 'Recipe',
          'menu_name' => 'Recipe',
          'add_new' => 'Add Recipe',
          'add_new_item' => 'Add New Recipe',
          'edit' => 'Edit',
          'edit_item' => 'Edit Recipe',
          'new_item' => 'New Recipe',
          'view' => 'View Recipe',
          'view_item' => 'View Recipe',
          'search_items' => 'Search Recipe',
          'not_found' => 'No Recipe Found',
          'not_found_in_trash' => 'No Recipe Found in Trash',
          'parent' => 'Parent Recipe',

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

Given the standard registration, you should have the following:

  • A post type with the name ‘recipe’
  • A recipe post archive at
  • Recipe posts with urls that take the form
  • A template archive-recipe.php
  • A template single-recipe.php

However, I see this in your registration code:

'rewrite' => array('slug' => ''),

This suggests what you’re trying to do is remove the ‘recipe’ prefix from recipe URLs. The result of this is that your recipe post archive is now:

site URL + ''

Which is already taken by the homepage, so your post archive is impossible to get to.

On top of this, it doesn’t actually do what you think it does. You can’t change a custom post type to not have the ‘/recipe/’ part in its URLs using the register_post_type rewrite parameters alone. You need to make other changes, which also introduce potentially site breaking bugs.

For example, if you have a page called ‘pumpkin’ and a recipe called ‘pumpkin’ how is WordPress to know which to load when visiting ? It doesn’t, so it’ll go for whichever rewrite rule it finds first.

So if you have a recipe for pie, but there’s no page called pie, and it looks for the page and doesn’t find it, you dont get the recipe, you get a 404.

So I would strongly advise you abandon your attempt. it makes your URLs make less sense, and despite the nonsense SEO “experts” say, it’s more likely to harm, not help your search engine rankings if it does anything at all ( it very likely does absolutely nothing to help you ).

So remove the rewrite parameter, and resave your permalinks


After you posted this link:

It is now clear that you’re loading a taxonomy and expecting a post type archive. A taxonomy is not a post type, as you can see here, they do not share the same fallbacks:

Post type archive page not working

What’s more it doesn’t make sense that they would. For example, which post type archive template would be used in these scenarios:

  • A taxonomy that contains 2 types of post type, people and locations. Would it fall back to archive-location.php or archive-people.php?
  • A user taxonomy, referring to users, not posts

So instead, use a taxonomy template for your taxonomy, not a post type archive template. In this case taxonomy-recipecategry.php

Method 2

Add this filter to your functions.php file:

function namespace_add_custom_types( $query ) {
  if( is_category() || is_tag() && empty( $query->query_vars['suppress_filters'] ) ) {
    $query->set( 'post_type', array(
     'post', 'nav_menu_item', 'your-custom-post-type-here'
      return $query;
add_filter( 'pre_get_posts', 'namespace_add_custom_types' );

All methods was sourced from or, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment