Free tools Windows power users keep installed
One-click scans. No signup required.
To keep password-protected posts out of your homepage, archives, or other front-end lists, either add has_password => false to a custom WP_Query or apply WordPress’s documented pre_get_posts/posts_where pattern to eligible main queries. The official pattern excludes protected posts without changing pagination, while leaving single posts, pages, and administration requests alone.
Choose the right scope
| Approach | Best for | Where it applies |
|---|---|---|
has_password => false |
A secondary loop or custom query you control | Only that WP_Query |
pre_get_posts with a posts_where condition |
A site-wide front-end rule for eligible main queries | Front-end lists, with explicit exclusions for single posts, pages, and admin requests |
Hide protected posts from the main front-end loop
WordPress’s official guidance uses a pre_get_posts callback to attach a posts_where filter. The filter adds AND {$wpdb->posts}.post_password = '', so only posts whose password field is empty remain in the query. The documented pattern is intended for a custom plugin file and is described as removing protected posts from list pages without affecting pagination.
Create a small custom plugin rather than placing the rule in a parent theme. For example:
<?php
/**
* Exclude password-protected posts from eligible front-end queries.
*/
function freedom251_hide_password_protected_posts( $query ) {
if ( is_admin() || is_single() || is_page() ) {
return;
}
add_filter(
'posts_where',
'freedom251_password_posts_where',
10,
2
);
}
add_action( 'pre_get_posts', 'freedom251_hide_password_protected_posts' );
function freedom251_password_posts_where( $where, $query ) {
global $wpdb;
$where .= " AND {$wpdb->posts}.post_password = ''";
return $where;
}
Save the file in a custom plugin, activate it under Plugins, and test the homepage and archive pages while logged out. Keep the condition narrowly scoped if your site has custom queries; a broad SQL filter can affect lists you did not intend to change.
#1 Best Overall
WordPress documents this approach in Protect posts with password. Its stated pagination behavior applies to that documented pattern; third-party themes, custom post types, query builders, and plugins can build queries differently and should be tested separately.
Exclude protected posts from one custom query
When you control the loop, put the condition in that query instead of changing every eligible front-end query:
Rank #2
$posts = new WP_Query( array(
'post_type' => 'post',
'posts_per_page' => 10,
'has_password' => false,
) );
In the WP_Query reference, has_password => false selects posts without passwords. Use has_password => true for protected posts only; null allows both kinds. This local approach is usually safer for a widget, related-posts section, shortcode, or plugin-owned list because it does not alter unrelated loops.
Why a list may still show a protected post
The theme runs a secondary query
A theme may create a new WP_Query after the main query. Add has_password => false to that query or adjust its own query arguments; changing the main query does not guarantee that every secondary loop follows the same rule.
Recommended Free Tools
A plugin or builder owns the query
Inspect the plugin’s query arguments or documented filters. If it constructs a custom query, the local has_password argument is more predictable than a site-wide SQL filter.
The list is a Query Loop block
The Query Loop block documentation describes category and tag filters and an option to exclude the current post, but it does not document a built-in password-status filter on that page. If the editor controls do not provide the condition you need, use a custom block/query solution or carefully scoped code, then verify behavior with the WordPress version and theme running on the site.
Rank #4
Password protection is not private visibility
A password-protected post can still expose its title and a password prompt; the password protects access to its content. WordPress describes private posts as visible only to users with the appropriate roles. Hiding a post from a loop changes that particular listing, not necessarily direct URL access, feeds, REST/API responses, metadata displays, or attached media.
When a template prints custom fields alongside a post, check post_password_required() before outputting sensitive field values. The guidance appears in WordPress’s password-protection documentation. For the distinction between protected and private content, see Set blog content visibility.
Quick Recap
Best Value
Verification checklist
- Create one normal post and one password-protected post.
- Check the homepage, category and tag archives, search results, widgets, and any related-posts areas that use separate queries.
- Confirm page counts and next/previous pagination still behave correctly after enabling the global pattern.
- Open the protected post directly to confirm that its intended password prompt still works.
- Test while logged out and, if relevant, with users who have different WordPress roles.
- Review feeds, API-driven displays, and custom-field templates separately if those surfaces must also conceal the post or its data.
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.

