Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
To create a custom post type archive in WordPress, enable has_archive when registering the post type, choose its rewrite slug, and add the template that matches your theme: archive-{post_type}.php for a classic theme or archive-{post_type}.html for a block theme. You do not need to create a normal WordPress Page—the archive is generated from the post type’s main query.
1. Identify the theme type and post type key
Your theme determines both the template format and where you customize the archive.
- Classic theme: uses PHP template files such as
archive-book.php. - Block theme: uses block templates such as
archive-book.html, or the Site Editor.
The filename uses the identifier passed to register_post_type(), not the human-readable label. If the registration key is book, the specific archive template is archive-book.php or archive-book.html, even if the public label is “Books.”
2. Register the post type with an archive
has_archive is false by default. Set it to true to create an archive route based on the post type key, or use a string to choose a distinct archive slug. The rewrite settings control URL rewriting, including the individual item slug and whether the site’s front base is included.
<?php
add_action( 'init', 'example_register_book_post_type' );
function example_register_book_post_type() {
register_post_type( 'book', array(
'public' => true,
'has_archive' => true,
'rewrite' => array( 'slug' => 'books' ),
'supports' => array( 'title', 'editor', 'thumbnail', 'excerpt' ),
) );
}
This example registers the type under the key book, gives its archive the books slug, and uses books for the individual post rewrite slug as well. Those two URL purposes can be configured independently when your information architecture requires different slugs.
Choosing the archive setting
| Setting | Result | Use it when |
|---|---|---|
'has_archive' => true |
The archive slug follows the post type key. | The public URL can align with the registration identifier. |
'has_archive' => 'books' |
The archive uses the chosen books slug. |
The public-facing wording should differ from the internal key. |
Rewriting must be enabled for WordPress to generate the archive rewrite rules. Check the expected slug against existing pages, taxonomies, and other routes before publishing it.
Where registration should live
Put registration in a plugin when the content type should remain available after a theme change. A type registered only in a theme disappears from the administration when that theme is replaced, although existing database content is not thereby converted into another post type.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Rank #2
3. Add the archive template for a classic theme
Create the file at the theme root using the exact post type key:
wp-content/themes/your-theme/archive-book.php
Use the normal WordPress loop in this file to output the archive heading, cards or rows, pagination, and other markup. The main query already contains the posts for the book archive, so the template normally loops over that query rather than creating another one.
WordPress checks classic archive templates in this order:
Rank #3
archive-book.phparchive.phpindex.php
A dedicated file is optional. If it does not exist, the broader archive or index template handles the request.
4. Add the archive template for a block theme
For a block theme, create the matching file in the theme’s templates structure:
wp-content/themes/your-theme/templates/archive-book.html
You can also customize the archive through Appearance > Editor (the Site Editor) when the active theme supports it. A template created by a user in the database can take priority over files supplied by the child or parent theme, so check the Site Editor if a file change appears to have no effect.
Rank #4
The block-template fallback order is:
archive-book.htmlarchive.htmlindex.html
Use Query Loop and other blocks to render the archive, while keeping the request’s existing post type query as the data source.
5. Build the archive from the main query
A post type archive is a query-driven index of that type’s posts, normally ordered as the latest published items. In a PHP template, is_post_type_archive() can test whether the current request is a post type archive, and post_type_archive_title() can output its title.
Do not create a second WP_Query merely to redisplay the posts already represented by the archive request. A separate query is appropriate only for a genuinely separate listing—for example, a sidebar selection or an additional group with different filters.
Best Value
Registering a post type also does not automatically add it to the home page or ordinary post archives. If another main listing must include that type, adjust that listing’s main query, commonly with pre_get_posts, rather than altering the archive template’s loop.
6. Refresh rewrite rules after registration changes
New or changed rewrite settings may not work until WordPress rebuilds its rewrite rules. The safe manual step is:
- Open Settings > Permalinks.
- Review the current permalink settings if needed.
- Click Save Changes, even if no setting changed.
- Test the archive URL and an individual post URL.
When a post type is registered in a plugin, flush rewrite rules on plugin activation after registration has run. A theme can use the corresponding theme-switch lifecycle. Do not call flush_rewrite_rules() on every request; rebuilding rules during normal page loads is unnecessarily expensive.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
7. Troubleshoot a missing or incorrect archive
The archive returns a 404
- Confirm the post type is registered on the
initaction. - Confirm
has_archiveis enabled and rewrites have not been disabled. - Check that the archive slug does not conflict with another page, taxonomy, or route.
- Save Settings > Permalinks once to refresh the rules.
The custom template is ignored
- Check that the filename uses the registration key, not the plural label.
- Confirm whether the site uses a classic or block theme and use the corresponding extension.
- For block themes, check the Site Editor for a database template that overrides the theme file.
- Verify the file is in the expected theme root or
templatesdirectory.
The archive shows the wrong posts
Inspect code that modifies the main query, including pre_get_posts callbacks and plugins that alter archives. A separate custom listing should use its own deliberate WP_Query; the archive template itself should normally render the archive’s supplied main query.
Quick Recap
Classic and block approaches compared
| Approach | Template route | Best fit | Trade-off |
|---|---|---|---|
| Classic theme | archive-{post_type}.php → archive.php → index.php |
Sites maintained through PHP theme files. | Rendering is flexible in PHP, but the template is maintained as theme code. |
| Block theme | archive-{post_type}.html → archive.html → index.html |
Sites edited with blocks and the Site Editor. | Database-created templates may outrank child- and parent-theme files. |
What you actually need
- An identifier registered with
register_post_type(). has_archiveset totrueor an archive slug.- Rewrite settings that do not conflict with existing routes.
- The matching PHP or HTML archive template, if the default fallback is not sufficient.
- A one-time permalink refresh after rewrite changes.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

