Let’s explore why the Payload search plugin is beneficial, how to install and configure it, and how to customize search fields for better results.
In this guide, we’ll focus on the official Payload Search Plugin, which provides:
There are two primary ways to implement search in Payload:
RegExp
query on specified fields. Uses listSearchableFields
in a collection’s config. Works well for small datasets, but slows down with large collectionsNote: While third-party search alternatives are useful, they require additional setup and maintenance. The Payload Search Plugin offers a built-in solution without external dependencies.
Before we implement the actual search logic, we’ll scaffold a minimal component that appears in the Payload admin. This lets us display search results inside the admin UI — without modifying Payload’s built-in dashboard.
Create a new file at src/components/BeforeDashboard.tsx
.
We’ll fill this in later, but for now, just register it in your Payload config:
Make sure you import the component:
Once that's wired up, you’ll see your custom UI render above the default dashboard in the Payload admin.
We'll come back and build out this component after setting up the plugin.
First, install the official search plugin: pnpm add @payloadcms/plugin-search
Next, open your Payload config (payload.config.ts
) and register the plugin:
This configuration: Enables search for blogArticles
and authors
. Creates a new search collection (searchResults
). Now, restart the development server: pnpm dev
Once the Payload Admin Panel reloads, you should see a new "Search Results" collection.
By default, the search collection will be empty. To populate it, we need to index existing data.
Payload provides a Reindex button in the Admin Panel.
Any new blog articles or authors added after this will be indexed automatically.
By default, the search plugin only stores the title. We can improve search accuracy by adding custom fields.
Modify the plugin config to include a description field:
This ensures each search entry stores a description.
Payload uses Lexical for rich text, which stores content in a deeply nested JSON structure. That’s not searchable by default.
To make it searchable, we flatten that content into plain text using a utility function.
We do this inside the beforeSync
hook, which gives us full control over what gets indexed.
In this hook, we extract and map rich text and relationship fields into unified title and description fields for better search results.
But first, we'll need to create a utility function into utils/extractPlaintText.ts
.
And be sure to import that into your Payload config: import { extractPlainText } from './utils/extractPlainText';
Next, we'll define the beforeSync
hook:
This ensures:
heading
as the title and content
as the description.name
as the title and bio
as the description.Return to the admin panel and reindex all the collections—you should see we have the title as either the author name or blog title, and the description field will have the content of either the author profile or blog article.
Now that indexing is set up, we’ll return to the BeforeDashboard.tsx
component we registered earlier and implement the actual search logic.
Next, we'll build a custom search input that queries the unified search collection created by the plugin. It performs a like search on both title and description, then displays results in a dropdown that links directly to the related documents in the Payload admin.
By implementing the Payload Search Plugin, we: