Back to Blog
Lesson 30 of the Intermediate WordPress Plugins: REST API & React Admin course
WordPressJune 26, 20263 min read

Building Search and Filter Functionality in WordPress REST API

Learn how to implement search and filtering for your WordPress Knowledge Base. We'll cover updating REST API GET requests, React state, and empty result handling.

wordpressphpplugin-development

Previously in this course, we covered Debugging React in the WordPress Admin to ensure our data flow was transparent and error-free. Now that our dashboard is stable, we need to make it useful. A dashboard with a hundred entries is unmanageable without a way to narrow down the view. In this lesson, we will implement search and filtering, moving from a simple "fetch all" approach to a dynamic, query-driven interface.

Concept: From Static Fetching to Query Parameters

When you first built your Knowledge Base service layer, you likely fetched all entries at once. For small datasets, this is fine. For anything larger, you need the server to do the heavy lifting.

The WordPress REST API allows you to pass query parameters to your GET requests. When you register your route, any parameters defined in the args array are automatically available in your callback via the $request object. By mapping these to WP_Query arguments, you shift the burden of filtering from your client-side React code to the database layer.

Updating the REST API Endpoint

First, we need to allow our endpoint to accept a search parameter. Open your PHP file where you defined your route. We need to add the parameter to the args array in your register_rest_route call.

PHP
#6A9955">// In your REST API registration logic
register_rest_route( 'kb/v1', '/entries', [
    'methods'  => 'GET',
    'callback' => 'kb_get_entries',
    'args'     => [
        'search' => [
            'validate_callback' => 'sanitize_text_field',
            'required'          => false,
        ],
    ],
] );

Now, update your kb_get_entries callback to use this parameter:

PHP
function kb_get_entries( WP_REST_Request $request ) {
    $args = [
        'post_type' => 'knowledge_base',
        's'         => $request->get_param( 'search' ),
    ];

    $query = new WP_Query( $args );
    #6A9955">// ... format and return your posts
}

Updating the React List Component

In your React component, you need a piece of state to track the search input and a way to trigger a re-fetch when it changes. We'll use a controlled component for the search input and useEffect to manage the request.

JSX
import { useState, useEffect } from CE9178">'react';
import { TextControl, Spinner } from CE9178">'@wordpress/components';
import { fetchEntries } from CE9178">'./service'; // Assuming your service layer

const KnowledgeBaseList = () => {
    const [search, setSearch] = useState(CE9178">'');
    const [entries, setEntries] = useState([]);
    const [loading, setLoading] = useState(false);

    useEffect(() => {
        setLoading(true);
        fetchEntries({ search }).then((data) => {
            setEntries(data);
            setLoading(false);
        });
    }, [search]);

    return (
        <div>
            <TextControl
                label="Search Entries"
                value={search}
                onChange={(val) => setSearch(val)}
            />
            {loading ? <Spinner /> : (
                entries.length > 0 ? (
                    <ul>{entries.map(e => <li key={e.id}>{e.title.rendered}</li>)}</ul>
                ) : (
                    <p>No entries found matching your search.</p>
                )
            )}
        </div>
    );
};

Hands-on Exercise: Implementing Debounced Search

Directly triggering an API call on every keystroke will spam your server. Your task is to implement a simple debounce mechanism.

  1. Install the lodash.debounce package or use a setTimeout inside your useEffect.
  2. Ensure that if the user clears the search input, the full list is re-fetched.
  3. Add a "Filter by Category" dropdown using the same args pattern in your PHP endpoint to practice multi-parameter filtering.

Common Pitfalls

  • The "Double Fetch" Trap: When adding complex state, useEffect can trigger multiple times during the initial mount. Always verify your dependency arrays.
  • Sanitization Neglect: Never pass raw $request parameters directly into WP_Query. Even if you aren't writing to the database, sanitize_text_field is mandatory to prevent potential injection or logic errors.
  • Empty State UX: Don't just show an empty list. Always provide a clear "No results found" message; otherwise, users will assume the dashboard is broken.
  • Over-fetching: If your search logic gets complex, ensure your REST API response isn't returning unnecessary fields. Use the _fields parameter in your client-side fetch if needed.

Recap

We have transitioned our Knowledge Base dashboard from a static data display to a dynamic, searchable interface. By leveraging the args parameter in the REST API, we optimized database queries, and by utilizing React state, we created a responsive UI that provides immediate feedback to the user.

Up next: We will cover Internationalization in React to ensure our plugin is ready for global users.

Similar Posts