Visit Agility Academy to take courses and earn certifications. It's free, and you can learn at your own pace. Learn More
Add search to your site
Next.js Search Starter for Agility CMS
We built a lightweight Search component you can customize and include in Next.js websites!
Check out the repo at https://github.com/agility/agilitycms-nextjs-starter-with-search for a fully built website starter.

Adding to your existing Next.js website
If you want to add this to your existing project, copy the following from the repo mentioned above.
/app/components/common/Search.tsx
This is the UI component built with Algolia's super fast Autocomplete library
Include the following within your application
<Search />
<MobileSearch />
/app/api/routes/search/route.ts
This is the API endpoint that handles the search, and also a webhook for updating the search index.
Setting up a webhook in Agility CMS
For instructions on adding a webhook to your Agility CMS instance, see this documentation.
To enable the updating of the search Index, setup a webhook in Agility for when content is saved and published to;
https://www.yourwebsite/api/search
Customizing the Search Index
By default the search index is mapped to our free trial starter content. You can customize as your liking by adjusting the following
As you can see in the example below, we do the following to pull out content we wish to populate our search index with. These should be customized to your component models.
1. Map all the content zones
2. Map all the page components in those zones
3. Return all the content found as strings
4. Join all the strings together
const pageContent = Object.keys(data.page.zones).map((zoneKey) => {
const zone = data.page.zones[zoneKey];
return zone.map((module: any) => {
let response = '';
if(module.module === 'PostDetails'){
response = data.contentItem.fields.content
}
if(module.module === 'RichTextArea'){
response = module.item.fields.textblob
}
if(module.module === 'TextBlockWithImage'){
response = module.item.fields.content
}
const strippedContent = response.replace(/<\/?[^>]+(>|$)/g, "").replace(/[\r\n]+/g, " ");
if(strippedContent !== ''){
return strippedContent;
}
}).join(' '); // Join modules into a single string
}).join(' '); // Join zones into a single string
Configuring FlexSearch
Depending on what exactly you want to be able to search, you can configure the FlexSearch document model as needed.
new FlexSearch.Document({
tokenize: 'full',
document: {
id: "id",
index: ["title", "content", "url"],
store: ["title","content", "url"],
},
context: {
resolution: 9,
depth: 2,
bidirectional: true,
},
});
1. index: Defines which fields should be indexed for searching.
• When you perform a search, FlexSearch looks up terms in the fields listed under index.
• The fields in index will be processed and optimized for fast searching.
• Example: If index: ["title", "content", "url"], it means FlexSearch will analyze the title, content, and url fields and allow searches to be performed based on the words within them.
2. store: Defines which fields should be stored and retrievable in search results.
• The store property specifies what data should be included in the search results.
• Without store, you might only get the document id as a result, and you’d have to look up the full data elsewhere.
• Example: If store: ["title", "content", "url"], when a search finds a match, the result will include these fields (instead of just the id).
If running in Vercel, Netlify or on an Edge Network
If running on an edge service where memory does not persist between requests, it is highly advised to use a hosted solution such as Algolia or SearchStax.
Although these features will run on the edge, depending on the size of your website, performance issues may occur and additional compute resources may be spent unnecessarily.