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

To remove every WordPress Page from the site’s native front-end search, filter the main search query with pre_get_posts and set its post_type to post. This changes the query before it runs while leaving dashboard searches untouched:

function search_filter( $query ) {
    if ( ! is_admin() && $query->is_main_query() ) {
        if ( $query->is_search() ) {
            $query->set( 'post_type', 'post' );
        }
    }
}
add_action( 'pre_get_posts', 'search_filter' );

Use a different method when you need to exclude only selected items, hide a custom post type site-wide, or support a live Ajax search that uses its own query.

Choose the right exclusion method

Requirement Method Main trade-off
Remove all Pages from native WordPress search pre_get_posts with post_type => 'post' Requires PHP and changes the native main search query.
Keep several content types but omit Pages pre_get_posts with an explicit allowed post-type array You must maintain the list as content types change.
Exclude a custom post type everywhere on the front end Register it with exclude_from_search => true Applies at the post-type level and can affect other search consumers.
Hide only a few Pages or Posts A per-item Search Exclude plugin Less code, but plugin compatibility and maintenance must be checked.
Filter a live Ajax search Use that search provider’s query/filter mechanism It may not run the same query as the normal browser search.

Remove all Pages from the native search

WordPress fires pre_get_posts after it has created query variables but before the database query executes. The callback below limits the change to the front-end main query and then restricts results to standard blog posts.

function search_filter( $query ) {
    if ( ! is_admin() && $query->is_main_query() ) {
        if ( $query->is_search() ) {
            $query->set( 'post_type', 'post' );
        }
    }
}
add_action( 'pre_get_posts', 'search_filter' );

Where to place the code

Add the callback in a site-specific plugin or a child theme’s functions.php. A site-specific plugin is usually safer for search behavior because the rule remains active when the theme changes. Test the change on staging before deploying it to production.

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

Why each condition matters

  • ! is_admin() prevents ordinary dashboard queries from being changed.
  • $query->is_main_query() limits the filter to the principal page query instead of secondary loops.
  • $query->is_search() ensures the restriction applies only to search requests.
  • $query->set( 'post_type', 'post' ) tells the query to return posts rather than Pages.

Using the query object’s methods is preferable to relying on global conditional functions inside this callback.

Keep other content types searchable

Setting the type to only post also removes products, documentation, events, or other custom post types. If those should remain searchable, provide an explicit allow-list:

function search_filter( $query ) {
    if ( ! is_admin() && $query->is_main_query() && $query->is_search() ) {
        $query->set( 'post_type', array( 'post', 'product' ) );
    }
}
add_action( 'pre_get_posts', 'search_filter' );

Replace product with the registered post-type names your site actually uses. An explicit array is safer than a broad any query when you know exactly which types visitors should search. WordPress documents post and page as explicit types; any also omits revisions and types marked exclude_from_search.

Exclude a custom post type at registration

For a custom post type that should never appear in front-end searches, set exclude_from_search to true when registering it:

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.
register_post_type( 'internal_note', array(
    'public' => true,
    'exclude_from_search' => true,
) );

This is a post-type-level setting. WordPress describes it as controlling exclusion from front-end searches such as site/?s=search-term; its default is derived from the post type’s public value. Keep registration in a plugin or must-use plugin so a theme switch does not remove the post type and its search behavior.

Hide only selected Pages without code

If the requirement is “exclude these few Pages,” rather than “exclude every Page,” a Search Exclude plugin is a closer fit. Such plugins add an exclusion control to the edit screen for Pages, Posts, and other content, allowing item-by-item decisions.

  • Install from a trusted source and review the plugin’s current compatibility and maintenance information.
  • Enable exclusion on each item that should not appear.
  • Test both the search results page and any search widgets or templates used by the theme.
  • Document the setting so editors know why an item is absent from results.

Handle Ajax and custom search providers

A live-search box may send an Ajax request to a plugin, theme, page builder, or external search service instead of using the normal front-end query. In that case, the pre_get_posts callback above may not control the returned list.

Some Ajax requests run with is_admin() true, so the ordinary front-end guard can prevent the callback from running. Do not remove that guard blindly: instead, identify the provider’s documented filter or query callback and apply the same post-type restriction there. If the provider exposes a WordPress query, use its equivalent of post_type and test the actual Ajax endpoint.

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

Verification checklist

  1. Search for a term that exists in both a Page and a Post.
  2. Confirm the normal results page shows the Post and omits the Page.
  3. Check that logged-in dashboard searches still behave normally.
  4. Test search widgets, header search, mobile search, and live suggestions separately.
  5. Clear page, object, and search-plugin caches before judging the result.
  6. Temporarily disable the rule to confirm whether a theme or plugin is supplying a separate query.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshoot Pages that still appear

The search is Ajax-powered

Follow the Ajax provider’s integration path rather than assuming the native main query is used. Inspect the provider’s settings or documentation for a post-type filter.

The callback is not loading

Check that the PHP file containing the function is active, that the function name is not duplicated, and that the site has no fatal error preventing it from loading.

A secondary loop is displaying Pages

The main-query restriction does not alter custom loops created by a theme or plugin. Those loops need their own query arguments or filters.

A custom type disappeared unexpectedly

If you changed the query to post, replace it with an explicit array containing every type that should remain searchable.

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

Old results are cached

Clear page and object caches, then test in a private browser window. Search engines and third-party indexes are separate from WordPress’s live query and require their own update or exclusion process.

What this change does—and does not do

  • It changes which content WordPress returns for the native front-end search query.
  • It does not delete Pages, change their URLs, block direct visits, or remove them from external search engines.
  • It does not automatically control theme-built, builder-built, Ajax, or third-party search interfaces.
  • It does not replace access-control measures for private or restricted content.

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.