Exclude Pages from WordPress Search Results

December 21, 2025
Exclude Pages from WordPress Search Results

By default, WordPress includes both posts and pages in search results.
In many real-world projects, however, pages such as landing pages, policy pages, or utility pages
should not appear in search results.

This article explains how to safely exclude pages from WordPress search results
using code-based approaches, why each method works, and when to choose one over another.

Why Pages Appear in WordPress Search

When a search request is made, WordPress internally runs a query equivalent to:

post_type = 'any'

This means:

  • Posts (post)
  • Pages (page)
  • Custom Post Types (if searchable)

To exclude pages, we must explicitly control the query before it is executed.

Recommended Approach: pre_get_posts

The safest and most flexible way is using pre_get_posts.
This hook allows you to modify the main query without breaking pagination or SEO.

Exclude All Pages from Search

<?php
add_action( 'pre_get_posts', function ( $query ) {
  if ( is_admin() ) {
    return;
  }

  if ( $query->is_main_query() && $query->is_search() ) {
    $query->set( 'post_type', array( 'post' ) );
  }
} );

This ensures:

  • Only applies to front-end searches
  • Only modifies the main query
  • Pages are completely excluded

Exclude Specific Pages by ID

If you want to keep pages searchable except for specific ones (e.g. Privacy Policy),
use post__not_in.

<?php
add_action( 'pre_get_posts', function ( $query ) {
  if ( is_admin() ) {
    return;
  }

  if ( $query->is_main_query() && $query->is_search() ) {
    $query->set( 'post__not_in', array( 12, 34, 56 ) );
  }
} );

This approach is useful when:

  • You want pages searchable by default
  • Only utility pages should be hidden

Exclude Pages Using a Custom Field (Scalable)

For larger sites, hardcoding IDs does not scale.
A better approach is controlling search visibility via a custom field.

Meta-based Exclusion Logic

<?php
add_action( 'pre_get_posts', function ( $query ) {
  if ( is_admin() ) {
    return;
  }

  if ( $query->is_main_query() && $query->is_search() ) {
    $meta_query = array(
      'relation' => 'OR',
      array(
        'key'     => '_exclude_from_search',
        'compare' => 'NOT EXISTS',
      ),
      array(
        'key'     => '_exclude_from_search',
        'value'   => '1',
        'compare' => '!=',
      ),
    );

    $query->set( 'meta_query', $meta_query );
  }
} );

With this approach:

  • Pages with _exclude_from_search = 1 are hidden
  • All other content remains searchable
  • No plugin dependency

Why Not Use exclude_from_search?

WordPress has a built-in argument called exclude_from_search,
but it only applies to post type registration.

This means:

  • It cannot exclude individual pages
  • It cannot be toggled per post
  • It requires re-registering post types

For fine-grained control, query-level filtering is the better choice.

Common Mistakes to Avoid

  • Using query_posts() (breaks pagination and globals)
  • Modifying queries without checking is_main_query()
  • Excluding pages via CSS or template logic only

SEO Considerations

Excluding pages from search results does not:

  • Block indexing by search engines
  • Change canonical URLs
  • Affect direct access to the page

If a page should not be indexed at all, use noindex instead.
Search exclusion and indexing control serve different purposes.

When to Exclude Pages from Search

  • Thank-you pages
  • Landing pages
  • Legal / policy pages
  • Utility or internal pages

Summary

Excluding pages from WordPress search is best handled at the query level.
Using pre_get_posts provides maximum control, safety, and scalability.

For production sites, prefer:

  • Post type filtering for simple cases
  • Meta-based exclusion for long-term maintainability
Avatar

Written by

satoshi

I’ve been building and customizing WordPress themes for over 10 years. In my free time, you’ll probably find me enjoying a good football match.