Change the Search-URL of WordPress

With WordPress it is easy to activate readable URLs. Only the search page is not affected by the setting yet, it comes with the syntax ?s as default. But there is a solution to change the URL as you wish.

The following example shows that even if you have permalinks activated, that the URL for the two searchterms wordpress and consulting looks like this: bueltge.de/?s=wordpress+consulting&submit=Search. With a little function, which communicates with the redirect, you can adjust the URL. In my case the URL with the two searchterms look like this with the following function: bueltge.de/search/wordpress+consulting.

Within WP-function wp_redirect I set the output, that the term search will be added to the home-url of your installation and added by the searchterms. There are many possibilities to adjust the URL.

function fb_change_search_url_rewrite() {
	if ( is_search() && ! empty( $_GET['s'] ) ) {
		wp_redirect( home_url( "/search/" ) . urlencode( get_query_var( 's' ) ) );
		exit();
	}	
}
add_action( 'template_redirect', 'fb_change_search_url_rewrite' );

Yes, it is also possible via htacces rules, but the source is an example for custom solutions on an redirect.

# search redirect
# this will take anything in the query string, minus any extraneous values, and turn them into a clean working url
RewriteCond %{QUERY_STRING} \\?s=([^&]+) [NC]
RewriteRule ^$ /search/%1/? [NC,R,L]

I would recommend to put the function in a Plugin or in the functions.php of your theme. Any other or better ideas to accomplish this? Please let us know in the comment area.

Comments are closed.

21 comments

  1. Mike

    Simple yet effective. Thanks

  2. Flixid

    Tried the script, but it fails:

    The page isn't redirecting properly
    Firefox has detected that the server is redirecting the request for this address in a way that will never complete.
    This problem can sometimes be caused by disabling or refusing to accept cookies.

    Native search works perfectly when this script is removed.

  3. Sylvain

    To prevent noobs from breaking down their wordpress, you should set a condition that watch if permalinks are enabled with :

    if ( get_option('permalink_structure') != '' ) {
    // the function here
    // the action here
    }

  4. Chuck Reynolds

    So I reposted this snippet over on forrst (giving you credit) and a guy had a good point.... Why don't you just use htaccess and make one http request instead of using this function?

    RewriteRule ^search/([^/]+)$ /search?s=$1 [NC]

  5. Otto

    Chuck: That works, but the point is to show a pretty URL to the end user in the URL bar, and unless you use a javascripty search form, that's hard to do from a form mechanism.

  6. Otto

    Although, to be fair, the .htaccess is a good route for this sort of thing. This code will probably do more what people are looking for:

    RewriteCond %{QUERY_STRING} s=(.*)
    RewriteRule ^$ /search/%1? [R,L]

    It will transparently change ?s=foo into /search/foo. WordPress has a rule for /search/ that should allow searches on it to work fine, if you're using non-default permalinks.

  7. Dion Hulse (@dd32)

    Another method one can use, is to add a onsubmit Javascript handler to the search form, which simply does location.href = '/search/' . URIComponentEncode(this.value); or similar.

    That .htaccess rule doesn't look like it'll work either, Needs to redirect ?s=xx to /search/$1 instead.

    Slashes and apostrophes can also provide problems, I belie get_query_var() will return the slashed form, which may striped/broken in the redirection code given..

  8. Frank

    At first; thanks for feedback and diskussion! Its nice to see, the people read us and diskuss the solutions! Also thanks for the great readers, all people has many reputations in WordPress.

    Yes, for the the goal to the rewrite the search url it is also possible to use the htaccess-way; but the snippet is also to see the possibilities in WordPress with small source and functions from the core; also an short view of an new possibility and maybe the start to a custom function for the own requirements.

    Also fine on this small example is, that you can add the keywords for feed and WordPress create on default the feed for the search keywwords; as example: hte feed for the keywords on the exmple on above is: bueltge.de/search/wordpress+consulting/feed/

  9. Nicholas

    Thank you for the cool snippet! Working well for me so far. I was wondering if it is possible to use this function to re-format custom post type urls?

    For example I have a site where I have a custom post type of "song". Thus the url is: /?song=song_name
    It would be preferable to have it as: /song/song_name

    I tried to use to use post_type_exists('song') as opposed to is_search() but this resulted in an endless redirect loop and the page fails to load.

    The other issue is that this would only check for a particular post type and not convert all post type urls.

    What could one do in this case?

  10. Peter Claus Lamprecht

    Thank you Frank, nice snippet.

    Unfortunately, search phrases like "Hello world" (with double quotes) don't work anymore.

    Any suggestions?

  11. Frank

    @Nicholas: i thinnk, a possibility is to set the var $wp_rewrite new for your CPT; check this var via var_dump() and you find your CPT. But an example for the search string of this post is the follow source:

    function fb_set_search_base() {
    
    	$GLOBALS['wp_rewrite'] -> search_base = 'my_search'; // set new string
    }
    add_action( 'init', 'fb_set_search_base' );
    

  12. Frank

    @Peter: i think the search phrase find no result with the WP default search, but also filter this and ready.

  13. Peter Claus Lamprecht

    @Frank
    Example string "easy to activate" (with double quotes).

    This works:
    http://wpengineer.com/?s=%22easy+to+activate%22

    This does not:
    http://wpengineer.com/search/%22easy+to+activate%22

    Why?

  14. Peter Claus Lamprecht

    @Frank
    With this function I solved the problem:
    function pcl_urldecode_s($query) {
    if ( is_search() ) {
    $query->query_vars['s'] = urldecode( $query->query_vars['s'] );
    }
    return $query;
    }
    add_filter('parse_query', 'pcl_urldecode_s');

  15. Monika T-S

    ;) I'll try a search like "humschdibums* on bueltge.de

    and so I saw an error 404 => logical

    Why should I start a mass-produce on error 404 and sent them with pretty permalinks to google?

    robots.txt
    Disallow: /?s*

    is the best way for search results ;)

  16. Frank

    @Peter: the snippet is here on WPEngineer not active, ist only a post about this solution.

    @Monika: thanks, but you can also comment on my german glob ;) i have include the string in robots.txt

  17. Monika T-S

    Yes I know Frank,
    I'd like to say with my example,
    it is nice to have the possibility " pretty permalinks for searchresults"-
    but who needs this?

    it is not the best for many websites to sent searchresults to Google or Yahoo, after a while you will have thousands of sites in Googles index - but this sites not always "quality sites" => "Panda " is the tender point. ;)

  18. Andrew Keith

    Hi Frank,

    Good post. I looked into this recently and found that you can use the WordPress Rewrite API (/wp-includes/rewrite.php) to achieve something similar to this:

    `
    function custom_search_url( $search_rewrite ) {
    if( !is_array( $search_rewrite ) ) { return $search_rewrite; }

    $new_array = array();
    foreach( $search_rewrite as $pattern => $s_query_string ) {
    $new_array[ str_replace( 'search/', 'my-search-url/', $pattern ) ] = $s_query_string;
    }
    $search_rewrite = $new_array;
    unset( $new_array );
    return $search_rewrite;
    }
    add_filter("search_rewrite_rules", "custom_search_url");

    `
    However, this won't redirect the "?s=" URLs. It customizes the search URL so that someone who goes to "/search/" will be directed to "/my-search-url/".

  19. Frank

    @Andrew: many thanks; nice solution wothout the htaccess idea. Thanks for the comment and your solution.

  20. kreso

    @otto

    I think you need something like this in htaccess

    RewriteCond %{QUERY_STRING} s=(.+)\&
    RewriteRule ^$ /search/%1/? [R,L]

    to remove that appended "&submit=Search" and to add final /

    and now it works!

    Thanks for great tip guys!

  21. Rajesh Namase

    Thanks for this code, working fine on my blog. I like your site.