Get In Touch

How to Create a Custom Search Form in WordPress (Code + Plugins)

Scroll

Home » Blog » WordPress » How to Create a Custom Search Form in WordPress (Code + Plugins)

WordPress’s default search form is barebones by design — one text field, one button, zero filtering. It searches post titles and content, ignores custom fields, and lumps products, pages, and blog posts into a single results page. If your visitors search for anything more specific than a keyword, they hit a wall.

The good news: fixing this doesn’t require a plugin, though a plugin can save real time if your site is large or your search needs go beyond post type filtering. This guide covers both paths — the searchform.php override for full control over markup and behavior, and the plugin route for sites that need relevance tuning, synonyms, or faceted search out of the box.

Why does the default WordPress search fall short?

The native WP_Query search only matches against post_title, post_content, and post_excerpt in the wp_posts table. It doesn’t touch custom fields (ACF, meta boxes), taxonomy terms, or WooCommerce product attributes unless you tell it to. It also can’t rank results by relevance — WordPress returns matches in date order, not by how well they match the query.

That’s fine for a small blog. It’s a problem for a documentation site, a multi-post-type site (blog + case studies + team bios), or a WooCommerce store where “search” needs to mean “product search.”

How do you create a custom search form in WordPress?

WordPress looks for a template file named searchform.php in your active theme (or child theme) before falling back to its built-in markup. Creating your own gives you full control over classes, labels, hidden fields, and accessibility markup.

Create searchform.php in your theme’s root folder:

<?php
/**
 * Custom search form template
 */
$unique_id = wp_unique_id( 'search-form-' );
?>
<form role="search" method="get" class="custom-search-form" action="<?php echo esc_url( home_url( '/' ) ); ?>">
    <label for="<?php echo esc_attr( $unique_id ); ?>" class="screen-reader-text">
        <?php esc_html_e( 'Search for:', 'your-theme' ); ?>
    </label>
    <input type="search"
           id="<?php echo esc_attr( $unique_id ); ?>"
           class="search-field"
           placeholder="<?php echo esc_attr_x( 'Search articles, products...', 'placeholder', 'your-theme' ); ?>"
           value="<?php echo get_search_query(); ?>"
           name="s" />
    <button type="submit" class="search-submit">
        <?php esc_html_e( 'Search', 'your-theme' ); ?>
    </button>
</form>

Once this file exists, WordPress automatically uses it anywhere get_search_form() is called — in your header, sidebar widget, or a search page template. You don’t need to register it or hook anything; the template hierarchy handles it.

To display the form anywhere in your theme:

<?php get_search_form(); ?>

If you want to output the markup as a string instead of echoing it (useful inside a shortcode or block), pass false:

<?php $form_html = get_search_form( false ); ?>

This is the same override pattern used for other theme customizations — the same logic applies when you build a custom 404 page in WordPress by dropping a 404.php file into your theme.

Default vs custom WordPress search form comparison

How do you customize the WordPress search form without a plugin?

Yes — most of what businesses ask for from a “custom search” (filtering by content type, excluding certain pages, changing what fields get matched) can be done with WordPress core hooks and zero plugins.

The two hooks that do the heavy lifting are pre_get_posts (to change what the query searches) and a hidden <input> field in your form (to pass extra parameters like post type).

Filter search results by post type with pre_get_posts

Add this to your theme’s functions.php or a site-specific plugin:

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

This restricts every front-end search to only those three post types — useful if you have custom post types (like team_member or testimonial) that shouldn’t clutter search results.

Let visitors choose the post type with a hidden field

If you want the search itself to be filterable — for example, a toggle between “search products” and “search articles” — add a hidden input or select dropdown to your searchform.php:

<select name="post_type" class="search-post-type">
    <option value="any"><?php esc_html_e( 'All content', 'your-theme' ); ?></option>
    <option value="post"><?php esc_html_e( 'Blog posts', 'your-theme' ); ?></option>
    <option value="product"><?php esc_html_e( 'Products', 'your-theme' ); ?></option>
</select>

Then adjust the pre_get_posts filter to respect whatever was submitted:

function whc_dynamic_post_type_search( $query ) {
    if ( $query->is_search() && ! is_admin() && $query->is_main_query() ) {
        if ( ! empty( $_GET['post_type'] ) ) {
            $post_type = sanitize_text_field( wp_unslash( $_GET['post_type'] ) );
            $query->set( 'post_type', $post_type );
        }
    }
}
add_action( 'pre_get_posts', 'whc_dynamic_post_type_search' );

This same “extend the query with a hidden or visible form field” pattern shows up constantly in WordPress customization work — it’s the same principle behind custom WordPress shortcodes that accept user-supplied attributes.

How do you limit search to specific post types?

Beyond the pre_get_posts hook above, there are two other common scenarios worth calling out:

  • Exclude pages entirely from search. Set post_type to array( 'post', 'product' ) and omit page — useful if your Pages are mostly navigational (About, Contact) rather than searchable content.
  • Search only within a single custom post type, like a knowledge base (kb_article). Set post_type to 'kb_article' directly, and consider adding a dedicated search form just for that section rather than overriding the global one.

For anything more advanced than post type filtering — like weighting title matches higher than body matches, or searching custom field values — you’re pushing against the limits of core WP_Query, which is where a search plugin starts to earn its cost (more on that below).

How do you style the search form with CSS?

Because you control the markup in searchform.php, styling is straightforward. A common pattern is an inline icon button with a focus state:

.custom-search-form {
    display: flex;
    align-items: center;
    max-width: 480px;
    border: 1px solid #d7dbe0;
    border-radius: 8px;
    overflow: hidden;
}

.custom-search-form .search-field {
    flex: 1;
    border: none;
    padding: 12px 16px;
    font-size: 15px;
    outline: none;
}

.custom-search-form .search-submit {
    border: none;
    background: #1a1a1a;
    color: #fff;
    padding: 12px 20px;
    cursor: pointer;
    transition: background 0.2s ease;
}

.custom-search-form .search-submit:hover {
    background: #333;
}

.custom-search-form .search-field:focus-visible {
    outline: 2px solid #2563eb;
    outline-offset: -2px;
}

Keep the :focus-visible state — it’s a small addition that meaningfully improves keyboard accessibility, and it’s the kind of detail that separates a template edit from a properly built custom form.

WordPress searchform.php and pre_get_posts code example

Which WordPress search plugins are worth it in 2026?

Custom code handles filtering and styling well. What it doesn’t handle well is relevance ranking, fuzzy matching, synonyms, or indexing custom fields and PDFs at scale. That’s the gap plugins fill. Here’s an honest comparison of the three most established options:

PluginBest forStrengthsWatch out for
SearchWPContent-heavy sites, custom fields, documentsGranular relevance engine, indexes ACF/meta fields, PDF content, and taxonomies; supports integrations for WooCommerce and BuddyPressPremium-only, pricing scales with site count
RelevanssiBlogs and mid-size content sites on a budgetFree tier covers most relevance-ranking needs; highlights matched terms in resultsFree version lacks some indexing options (custom fields, taxonomy weighting) reserved for premium
FiboSearchWooCommerce storesPurpose-built AJAX product search with live thumbnails, price, and stock status as you typeWeaker for searching non-product content like blog posts

When is the native approach enough? If your site is a blog, a small brochure site, or has fewer than a few hundred posts, searchform.php plus a pre_get_posts filter will cover 90% of what a client asks for — post type filtering, excluding certain content, basic styling. Reach for a plugin when you need relevance scoring, custom field indexing, typo tolerance, or search analytics you don’t want to build yourself.

How should WooCommerce stores handle product search?

Product search has different requirements than content search: shoppers expect live results as they type, thumbnails, price, and stock status — not a results page they have to click through to evaluate. This is exactly the gap FiboSearch and similar AJAX search plugins are built for.

If you’re not ready for a dedicated plugin, you can still scope the default search to products only on category or shop pages using the same pre_get_posts filter pattern above, restricting post_type to product when is_shop() or a product category archive is active. For a store built on a fully custom WordPress development foundation, product search is usually worth building as its own component rather than retrofitting the blog search — the query logic, sorting (by relevance vs. by price), and result card markup are different enough to justify separating them.

If your team needs this built rather than DIY’d, that’s the kind of scoped, well-defined task that fits well into custom WordPress plugin development work — a small, purpose-built plugin rather than a general-purpose search add-on you don’t fully need.

WooCommerce AJAX product search with live results

Frequently Asked Questions

Can I create a custom search form without a plugin?

Yes. WordPress core supports this natively through a searchform.php template override in your theme, combined with the pre_get_posts hook to control which post types and fields are searched. No plugin is required for form markup, styling, or post-type filtering — you only need a plugin when you want relevance ranking, synonym matching, or indexing of custom fields at scale.

How do I customize the WordPress search form’s HTML and styling?

Create a searchform.php file in your active theme’s root directory. WordPress automatically detects and uses it wherever get_search_form() is called, including in widgets and header templates. From there, style it with regular CSS classes — there’s no special markup requirement beyond keeping the name="s" attribute on your text input, since that’s what WordPress reads to run the query.

How do I limit WordPress search to specific post types?

Use the pre_get_posts action hook, check $query->is_search() and $query->is_main_query(), then call $query->set( 'post_type', array(...) ) with the post types you want included. This runs before the query executes, so it affects the actual results rather than filtering them after the fact.

What’s the best WordPress search plugin in 2026?

It depends on the site. SearchWP is the strongest choice for content-heavy sites that need custom field and document indexing. Relevanssi is a solid free option for blogs needing better relevance ranking without a budget. FiboSearch is purpose-built for WooCommerce stores that need live AJAX product search with thumbnails and pricing.

Does a custom search form help SEO?

Indirectly, yes. A search that actually returns relevant results keeps visitors on-site longer and reduces bounce rate, both of which are positive engagement signals. It also reduces “no results found” pages, which are a poor experience for both users and any internal linking value those visits could generate.

Get your search built right the first time

A custom search form is a small piece of code, but it’s one visitors interact with directly — get the post-type filtering or the product search UX wrong, and it shows immediately. If you’d rather have it built and tested than debug pre_get_posts conflicts yourself, our team handles this as part of custom WordPress development engagements, and can scope it as standalone WordPress plugin development if you just need the search component.

You might also find useful:

Alex Founder Web Help Agency

Alex

Founder

a moment ago

Looking for web developers?

Ready to chat? Simply click the button and select your preferred call time.

Let's discuss it chat-bubble