How to Sort WordPress REST API Results by Custom Fields

By default, sorting WordPress posts by a custom field is straightforward when using WP_Query—you simply pass the corresponding order parameters. However, achieving the same result within the WordPress REST API is not as intuitive because the API restricts the orderby parameter to a specific set of allowed values.

The standard orderby values for the REST API include: author, date, id, include, modified, parent, relevance, slug, include_slugs, title. If you attempt to pass any value outside of this list, the API will return a rest_invalid_param error like this:

{
  "code": "rest_invalid_param",
  "message": "Invalid parameter(s): orderby",
  "data": {
    "status": 400,
    "params": {
      "orderby": "orderby is not one of author, date, id, include, modified, parent, relevance, slug, include_slugs, title."
    }
  }
}

Fortunately, we can use the rest_{post_type}_collection_params filter to whitelist additional fields for sorting. Here is how to implement custom sorting.

1. Enabling menu_order Sorting

To enable sorting by menu_order for standard posts or custom post types (like a ‘portfolio’), use the following code snippet:

// Enable orderby=menu_order for standard posts
add_filter( 'rest_post_collection_params', 'filter_add_rest_orderby_params', 10, 1 );

// Enable orderby=menu_order for a 'portfolio' custom post type
add_filter( 'rest_portfolio_collection_params', 'filter_add_rest_orderby_params', 10, 1 );

function filter_add_rest_orderby_params( $params ) {
    $params['orderby']['enum'][] = 'menu_order';
    return $params;
}

Once this filter is added to your theme’s functions.php or a custom plugin, the REST API will respect the menu_order parameter, allowing you to return posts in the exact order you’ve specified in the WordPress admin.

2. Sorting by Custom Meta Fields

If you need to sort by custom fields—such as post views, area, or even a random order—the process is similar but requires an additional step to tell the underlying query how to handle these new values.

First, add your custom keys to the allowed enum list:

add_filter('rest_post_collection_params', function($params) {
    $params['orderby']['enum'][] = 'views';
    $params['orderby']['enum'][] = 'area';
    $params['orderby']['enum'][] = 'random';
    return $params;
}, 10, 1);

Next, use the rest_{post_type}_query filter to map these parameters to the actual WP_Query arguments:

add_filter('rest_post_query', function ($query_vars, $request) {
    $orderby = $request->get_param('orderby');

    if (isset($orderby)) {
        if ($orderby === 'views') {
            $query_vars["orderby"]  = "meta_value_num";
            $query_vars["meta_key"] = "wl_pageviews";
        } elseif ($orderby === 'area') {
            $query_vars["orderby"]  = "meta_value_num";
            $query_vars["meta_key"] = "area";
        } elseif ($orderby === 'random') {
            $query_vars["orderby"] = "rand";
        }
    }

    return $query_vars;
}, 10, 2);

Sorting is a fundamental requirement in almost every application. While the WordPress REST API is strict by default, these filters provide the flexibility needed to build powerful, custom-sorted content feeds for your frontend applications.

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *