Set a custom /path for WordPress search result pages

Create a site-search landing page, separate your front page and search result pages in analytics, and make your search links explain themselves by adding a custom /search path to your WordPress website.

This tutorial assumes your WordPress website is configured to use what is known as “pretty” permalinks (rewrites), and that you’ve got access to modify your server configuration (e.g. .htaccess).

Why you’d want a custom path for search results

You probably already have a good idea of why you’d want to add a custom path to your search result pages if you’re reading this article. Anyhow, here are some of the reasons that I had for separating search result pages in WordPress out from the base path shared with the front page and over to their own URL path:

  • A linkable site-search landing page for my site navigation menu
  • Make it easier to separate the front page and search result pages in my web analytics software
  • Make it possible to ignore query parameters for every other path (for proxy caching purposes)
  • Vanity URL – it looks better and the URL says clearly that it’s a search

Rewrite the path

WordPress will treat a request with the s query parameter set as a search, so essentially all you have to do is to mask the custom path and rewrite the traffic so that WordPress’ index.php file will handle it.

For Apache Web Server:

RewriteCond %{REQUEST_URI} "^/search"
RewriteRule "^/search(/page/([0-9]+))?$" "/index.php?paged=$2&s" [QSA]

For NGINX:

location "/search" {
  rewrite "^/search(/page/([0-9]+))?$" "/index.php?paged=$2&s";
}

There are a few different things going on in the above rewrite rule, and I’ll try to explain each of them in turn. Firstly, the rule is only triggered when the request URI is /search (marked in blue in all code examples where you’d have to change it to set your own path). Note that the rewrite rule doesn’t trigger a redirect but only an internal remapping of the requested URL into WordPress core.

We then set the paged query parameter from the request URI, or it will be set to an empty value when requesting the first page and thus ignored. Your theme should handle appending numbered page suffixes like /page/2 to the end of your custom search path without any additional tweaking to your WordPress theme. You may have to undo some existing customization to your search result pagination links if this isn’t the case.

Lastly, we set an empty s (search) query parameter. This empty parameter is ignored in favor of an existing/user-provided query if supplied. However, the empty search value will trigger an empty search and thus ensuring that WordPress will always treat the custom search path as a search page even when no keywords have been provided. By default, WordPress will return all posts in chronological order when triggering an empty search. However, setting this empty parameter allows you to create things like a site search oriented landing page by further tweaking your theme.

The QSA flag in the Apache configuration example, short for “query string append”, at the end of the rule merges the existing/visitor-provided query parameter with our hardcoded query options. This is the default behavior in NGINX.

Updating the search form

Now that the custom search path should be working, it’s time to modify the search form to direct traffic to the new address. Depending on how your theme is setup, you should find the search form in searchform.php. All you need to do is to add your custom /search path to the form’s action attribute.

<form … action="<?php echo esc_url(home_url('/search')); ?>">

Optional: Redirect the default search links to the custom path

WordPress’ default search URLs will still work as-is alongside your new custom search path unless you redirect them to the new path. However, search engines generally don’t like it when the same content resides on multiple addresses. You can reduce content duplication and push every visitor over to the same URLs by redirecting the old WordPress-default URL to the new URLs.

For Apache Web Server:

RewriteCond %{QUERY_STRING} "(^s=|&s=)"
RewriteCond %{REQUEST_URI} "!/(search|wp-admin)"
RewriteRule "(.*)" "/search" [redirect=301,last]

For NGINX:

location ~ "/(?!search|wp-admin)" {
  if ($arg_s != false)
    rewrite "(.*)" "/search" last;
} }

The above redirects triggers a redirect for URLs that contain the search query parameter (s=) on any path other than your custom search path to the new search path (/search). Note that special $arg_s in the NGINX code configuration example variable holds the value, if any, of the s string query parameter.

Remember to also update your OpenSearch description file, Schema.org SearchAction, or other integration points that depends on how your website builds its search URLs.