One of our readers recently asked if it's possible to enable sticky posts for custom post types in WordPress. While WordPress supports sticky posts for standard posts out of the box, this feature isn't available for custom post types by default. In this guide, drawn from years of hands-on WordPress development, we'll walk you through enabling sticky functionality for your custom post types. Before diving in, consider reviewing how to create custom post types in WordPress if needed.
To get started, install and activate the Sticky Custom Post Types plugin. Once activated, head to Settings » Reading and scroll down to the Sticky Custom Post Types section. Select the custom post types where you want sticky post support.

This enables sticky posts for your chosen custom post types, which will now appear on the front page just like regular sticky posts.
However, WordPress only displays sticky posts on the home or blog page by default—not on archive pages.
For example, suppose you have a movie-reviews custom post type with sticky posts enabled via the plugin. To show sticky movie reviews at the top of the archive page (above non-sticky ones), first create a custom archive template like archive-movie-reviews.php. Learn how to create a custom post type archive page. Simply copy archive.php from your theme and rename it to archive-your-post-type.php in your theme folder.
Next, add this proven code snippet to your theme's functions.php file:
function wpb_cpt_sticky_at_top( $posts ) {
// Apply this only on the CPT archive page
if( !is_main_query() || !is_post_type_archive() )
return $posts;
global $wp_query;
$sticky_posts = get_option( 'sticky_posts' );
$num_posts = count( $posts );
$sticky_offset = 0;
// Loop over posts and find sticky ones
for( $i = 0; $i < $num_posts; $i++ ) {
if( !in_array( $posts[$i]->ID, $sticky_posts ) )
continue;
// Put sticky posts at the top of the posts array
$sticky_post = $posts[$i];
// Remove this post from its current position
array_splice( $posts, $i, 1 );
// Move it to the front, after other stickies
array_splice( $posts, $sticky_offset, 0, array( $sticky_post ) );
$sticky_offset++;
// Remove post from the sticky posts array
$offset = array_search( $sticky_post->ID, $sticky_posts );
unset( $sticky_posts[$offset] );
}
// Find sticky posts that weren't in the query
if( !empty( $sticky_posts ) ) {
$stickies = get_posts( array(
'post__in' => $sticky_posts,
'post_type' => $wp_query->query_vars['post_type'],
'post_status' => 'publish',
'nopaging' => true
) );
foreach ( $stickies as $sticky_post ) {
array_splice( $posts, $sticky_offset, 0, array( $sticky_post ) );
$sticky_offset++;
}
}
return $posts;
}
add_filter( 'the_posts', 'wpb_cpt_sticky_at_top' );
// Add 'sticky' class to sticky posts for styling
function cpt_sticky_class( $classes ) {
if( is_sticky() ) {
$classes[] = 'sticky';
}
return $classes;
}
add_filter( 'post_class', 'cpt_sticky_class' );This code moves your sticky posts to the top of the archive and adds a sticky class to them (if your theme uses the post_class() function). Style them easily with CSS:
.sticky {
background-color: #f7f7f7;
background-image: url('https://example.com/wp-content/uploads/featured.png');
background-repeat: no-repeat;
background-position: top right;
}
We hope this detailed guide helps you successfully implement sticky posts for custom post types. If you have questions, drop a comment below.
Source: Tareq Hasan