Change Number of Posts Displaying on a Custom Post Type (CPT) Archive Page

To change the number of posts that appear in an archive page for a custom post type you can change the number using the pre_get_posts action with some passed in parameters.

Normally the number of posts displayed per page is defaulted to the setting in the Dashboard Reading Settings > Blog pages show at most – you may want regular posts to have this number but a different number for CPTs.

Custom Post Type Archive Pages

pre_get_posts is like a pre-filter of the main query that runs on a page – if you are altering such a page it is better to more efficient to use pre_get_posts rather than use a new WP_query()

add_action( 'pre_get_posts', 'tl_project_page' );
// Show all Projects on Projects Archive Page
function tl_project_page( $query ) {
    if ( !is_admin() && $query->is_main_query() && is_post_type_archive( 'project' ) ) {
            $query->set( 'posts_per_page', '-1' );

So all the project posts would show on the project archive page this is done by setting the value of posts_per_page to -1.

Change to your CPT registered value of what is passed into is_post_type_archive.

Multiple Custom Post Type Archive Pages

If you want to set a number of CPTs to the same value, say unlimited posts you can use an array to include mutiple CPTs instead of duplicating the code – changing this part of the code…

is_post_type_archive( array('project', 'treatment', 'testimonial') )

Taxonomy Archive Pages

Similarly if you wanted to change the number of a custom taxonomy page..

add_action( 'pre_get_posts', 'tl_project_tax_page' );
// Show all Projects on Projects Archive Page
function tl_project_tax_page( $query ) {
    if ( !is_admin() && $query->is_main_query() && is_tax('project_category') ) {
            $query->set( 'posts_per_page', '-1' );

Here the target is is_tax() and the posts_per_page is also set to -1, change to your desired number and taxonomy.

The use of !is_admin() is not to affect the backend display don’t use this condition if you do want to change the backend listing and the use of $query->is_main_query() ensures no other queries on the page are affected.

Other Query Parameters

You can use multiple parameters to alter the query including some below…

$query->set( 'orderby', 'title' );
$query->set( 'order', 'ASC' );
$query->set( 'post__not_in', array(7,11) ); // Exclude Posts
$query->set( 'cat', '-1,-1347' ); // Exclude Categories
$query->set( 'cat', '123' ); // Include Categories

The various values of these parameters can be referenced on the Codex.

Also parameters can be set on any used custom fields using meta_query.