Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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:

$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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.