Troubleshooting Custom Post Type Archive Pagination and Duplicate Posts
Content
If you've created a custom post type (CPT) archive page and then tried to modify the query to sort or change the number of posts, you may have encountered a frustrating issue: duplicate posts appearing on the first page or the archive functionality breaking entirely. This is a common problem that stems from how the main query is modified.
Why This Happens
When you use functions like query_posts() or create a new WP_Query on an archive template without carefully preserving the original query variables, you can inadvertently overwrite the main query. The original query already contains crucial information, such as the post type and pagination data. When you replace it with a new query that doesn't include this context, WordPress can no longer correctly identify that it should only be displaying posts from your specific CPT, leading to unexpected results like duplicate posts or all posts being displayed.
Common Solutions
1. Use the pre_get_posts Hook (Recommended)
The most robust method for modifying queries, especially on archive pages, is to use the pre_get_posts action hook within your theme's functions.php file. This method alters the query before it is run, avoiding the issues caused by overwriting it later.
function my_modify_cpt_archive_query( $query ) {
// Check if on the front end and the main query for your CPT archive
if ( ! is_admin() && $query->is_main_query() && is_post_type_archive( 'your_cpt_slug' ) ) {
$query->set( 'orderby', 'title' );
$query->set( 'order', 'ASC' );
$query->set( 'posts_per_page', 30 ); // Change number of posts
}
}
add_action( 'pre_get_posts', 'my_modify_cpt_archive_query' );
2. Properly Use query_posts() with $query_string
If you must modify the query directly in your template file (e.g., archive-your_cpt.php), ensure you append the original query string. This helps preserve the context of the query, such as the post type and pagination information.
// Append to the original query instead of replacing it
query_posts( $query_string . '&orderby=title&order=asc&posts_per_page=30' );
// Your loop here
wp_reset_query(); // Always reset when done
3. Explicitly Define the Post Type
When creating a custom query, always explicitly define the post type you are querying. This prevents the query from defaulting to the standard 'post' type.
// For a new WP_Query
$custom_query = new WP_Query( array(
'post_type' => 'your_cpt_slug', // This is critical
'orderby' => 'title',
'order' => 'ASC',
'posts_per_page' => 30,
'paged' => get_query_var( 'paged' ) // Important for pagination
) );
// Your loop using $custom_query here
wp_reset_postdata(); // Reset post data after a custom query
Important Considerations
- Avoid query_posts(): The
query_posts()function is not recommended by many developers because it completely overrides the main query and can cause significant performance and compatibility issues. Usingpre_get_postsor a secondaryWP_Queryis preferred. - Pagination: If you change
posts_per_page, ensure you include'paged' => get_query_var( 'paged' )in your custom query arguments so pagination functions likenext_posts_link()work correctly. - Reset Queries: Always use
wp_reset_query()afterquery_posts()andwp_reset_postdata()after a customWP_Queryto restore the global$postdata and main query.
By understanding how WordPress handles its main query and using the correct methods to modify it, you can successfully create sorted and paginated custom post type archives without encountering duplicate posts or other unexpected behavior.
Related Support Threads Support
-
post_author field on wp.newPost call in XMLRPC API not working as expectedhttps://wordpress.org/support/topic/post_author-field-on-wpnewpost-call-in-xmlrpc-api-not-working-as-expected/
-
Incorrect # of postingshttps://wordpress.org/support/topic/incorrect-of-postings/
-
search multiple taxonomies (witch checkboxes)https://wordpress.org/support/topic/search-multiple-taxonomies-witch-checkboxes/
-
In Admin Panel, Filter posts by category not workinghttps://wordpress.org/support/topic/in-admin-panel-filter-posts-by-category-not-working/
-
WP 3.1 breaks RSS customization via exclude_category?https://wordpress.org/support/topic/wp-31-breaks-rss-customization-via-exclude_category/
-
Custom WP_query in RC4 add ID of page set as frontpage to queryhttps://wordpress.org/support/topic/custom-wp_query-in-rc4-add-id-of-page-set-as-frontpage-to-query/
-
Sticky Posts not workinghttps://wordpress.org/support/topic/sticky-posts-not-working-3/
-
Pre Get Posts issue with is_category()https://wordpress.org/support/topic/pre-get-posts-issue-with-is_category/
-
Function for neighbouring posts, broken by 3.1-beta1https://wordpress.org/support/topic/function-for-neighbouring-posts-broken-by-31-beta1/
-
WP3.1-RC4 & filter query (with meta key) not workinghttps://wordpress.org/support/topic/wp31-rc4-filter-query-with-meta-key-not-working/
-
Members Only Posts/Pageshttps://wordpress.org/support/topic/members-only-postspages/
-
wp_query exclude categories not workinghttps://wordpress.org/support/topic/wp_query-exclude-categories-not-working/
-
passing a single taxonomy as a string to WP Term Query returns errorhttps://wordpress.org/support/topic/passing-a-single-taxonomy-as-a-string-to-wp-term-query-returns-error/
-
3.1 RC2 Adding any query to CPT archive removes archive functionalityhttps://wordpress.org/support/topic/31-rc2-adding-any-query-to-cpt-archive-removes-archive-functionality/
-
Exclude Authorshttps://wordpress.org/support/topic/exclude-authors-1/
-
Custom post type Archive duplicates posts if Sorted (by title for example)https://wordpress.org/support/topic/custom-post-type-archive-duplicates-posts-if-sorted-by-title-for-example/
-
Wp_get_post_revisions doesn't return latest revision firsthttps://wordpress.org/support/topic/wp_get_post_revisions-doesnt-return-latest-revision-first/
-
WP 3.3 RC2 – RSS excerpt and content functions INOPhttps://wordpress.org/support/topic/wp-33-rc2-rss-excerpt-and-content-functions-inop/
-
is_post_type() within the loop?https://wordpress.org/support/topic/is_post_type-within-the-loop/
-
Pagination problemhttps://wordpress.org/support/topic/pagination-problem-22/
-
Wp_Query not randhttps://wordpress.org/support/topic/wp_query-not-rand/
-
"Blog pages show at most" affects admin screenshttps://wordpress.org/support/topic/blog-pages-show-at-most-affects-admin-screens/
-
Does get_posts() support tax_query? RC4https://wordpress.org/support/topic/does-get_posts-support-tax_query-rc4/
-
Net sales not accurate on analytics pageshttps://wordpress.org/support/topic/net-sales-not-accurate-on-analytics-pages/
-
Calling ‘have_posts()’ in a custom block returns falsehttps://wordpress.org/support/topic/calling-have_posts-in-a-custom-block-returns-false/
-
feed.php fails in 3.5https://wordpress.org/support/topic/feedphp-fails-in-35/
-
Sorting Pages by Title with Parent/Child relationships?https://wordpress.org/support/topic/sorting-pages-by-title-with-parentchild-relationships/
-
post_content interception, doesn't work anymorehttps://wordpress.org/support/topic/post_content-interception-doesnt-work-anymore/
-
Pagination on static homepage stopped workinghttps://wordpress.org/support/topic/pagination-on-static-homepage-stopped-working/
-
get_users_of_blog() changed in 3.1https://wordpress.org/support/topic/get_users_of_blog-changed-in-31/
-
Filter Posts By Category Not Workinghttps://wordpress.org/support/topic/filter-posts-by-category-not-working/
-
4.2-alpha title-tag bughttps://wordpress.org/support/topic/42-alpha-title-tag-bug/