The WordPress REST API is one of my favourite features in WordPress. The ability to create custom endpoints for getting data and other facets of building in WordPress makes life so much easier.

Recently, while building a custom endpoint that allowed for some custom post type content to be searched, I encountered a snag.

register_rest_route( 'raw-queue/v1', '/queue/(?P<name>[a-zA-Z0-9-]+)/(?P<results>[\d]+)/(?P<page>[\d]+)/(?P<source>[a-zA-Z0-9-]+)/(?P<term>([a-zA-Z])+)', array(   'methods' => 'GET',   'callback' => 'rest_get_news_stories_from_category',   'permission_callback' => '__return_true' ) );

For singular search terms, it worked well. However, once I searched for words like "basketball player", I would get the dreaded 404 error.

It turns out you need to tell WordPress in your regular expression path to allow the %20 character (which is a space). By default, spaces are ignored (as are other characters).

register_rest_route( 'raw-queue/v1', '/queue/(?P<name>[a-zA-Z0-9-]+)/(?P<results>[\d]+)/(?P<page>[\d]+)/(?P<source>[a-zA-Z0-9-]+)/(?P<term>([a-zA-Z]|%20)+)', array(   'methods' => 'GET',   'callback' => 'rest_get_news_stories_from_category',   'permission_callback' => '__return_true' ) );

Notice the |%20 part in the route pattern? That tells WordPress we are okay with spaces in our route, and it will no longer break. Now, search terms like basketball%20player will work with our route. You can add in additional URL characters as you need them.

Now, last and most importantly, inside of your route callback, you need to make sure you use urldecode to remove the characters from the URL.

urldecode($request->get_param('term'));