Search API

Implement search using Drupal Search API.


You need to install the JSON:API Search API module to query your Search API indexes.


Installation

  1. Start by installing the Search API module. If you want faceted search, install the Facets module as well.
composer require drupal/search_api drupal/facets drupal/jsonapi_search_api drupal/jsonapi_search_api_facets
  1. Enable the following modules: Search API, Database Search, Facets, JSON:API Search API and JSON:API Search API Facets.
  2. Create a server and index by following the guide here.

For every index created, a facet source is available. You can use this source to create filters.

  1. Visit /admin/config/search/facets and click on Add facet.
  2. Under Facet source, select the server created above. For Field, select the field to filter on. Save.
  3. Next, edit the facet and make sure JSON:API Search API is selected under widget.
  4. You can now make queries to your indexes via JSON:API.
import { drupal } from "lib/drupal"
const results = await drupal.getSearchIndex(indexName, {
params: {
filter: { name_of_field: value },
},
})

Implementation

We recommend using an API route for querying the search index. Using an API route means you can share search indexes, implement rate limiting and filtering using middlewares.

  1. Create the following API route.

api/pages/[index].tsx

import { NextApiRequest, NextApiResponse } from "next"
import { DrupalNode } from "next-drupal"
import { drupal } from "lib/drupal"
export default async function handler(
request: NextApiRequest,
response: NextApiResponse
) {
try {
const body = JSON.parse(request.body)
const { index } = request.query
const results = await drupal.getSearchIndex<DrupalNode>(
index as string,
body
)
response.json(results)
} catch (error) {
return response.status(400).json(error.message)
}
}
  1. To make a search request from your React component, you can use a simple fetch request.
const response = await fetch("/api/search/INDEX-NAME-HERE", {
method: "POST",
body: JSON.stringify({
params: {
filter: { name_of_field: value },
},
}),
})

Localized Search Results

Next.js API Routes have no context of the current locale. For localized search results, you should pass the locale and defaultLocale from the router.

const router = useRouter()
const response = await fetch("/api/search/INDEX-NAME-HERE", {
method: "POST",
body: JSON.stringify({
params: {
filter: { name_of_field: value },
},
locale: router.locale,
defaultLocale: router.defaultLocale,
}),
})

Demo

See https://example-search-api.next-drupal.org.

Example

See https://github.com/chapter-three/next-drupal/tree/main/examples/example-search-api