Skip to content

Search integration

Search Integration

When to Use

Implement search functionality using Drupal Search API exposed via JSON:API.

Steps

1. Install required modules

composer require drupal/search_api drupal/jsonapi_search_api
# Optional for faceted search
composer require drupal/facets drupal/jsonapi_search_api_facets

Enable: Search API, Database Search, JSON:API Search API (and Facets modules if needed).

2. Create search index in Drupal

Visit /admin/config/search/search-api: - Add Server (Database) - Add Index (e.g., "content_index") - Select datasources (Content, Users, etc.) - Add fields to index (title, body, etc.) - Configure processors - Save and index content

3. Create facets (optional)

Visit /admin/config/search/facets: - Click "Add facet" - Facet source: Select your search index - Field: Select field to facet on - Widget: JSON:API Search API - Save

4. Create search API route in Next.js

// app/api/search/[index]/route.ts
import { NextRequest, NextResponse } from "next/server"
import { drupal } from "@/lib/drupal"

export async function POST(
  request: NextRequest,
  { params }: { params: { index: string } }
) {
  try {
    const body = await request.json()

    const results = await drupal.getSearchIndex(params.index, {
      params: body.params,
      locale: body.locale,
      defaultLocale: body.defaultLocale,
    })

    return NextResponse.json(results)
  } catch (error) {
    return NextResponse.json(
      { error: (error as Error).message },
      { status: 400 }
    )
  }
}

5. Query from frontend

// In a client component
const handleSearch = async (term: string) => {
  const response = await fetch("/api/search/content_index", {
    method: "POST",
    body: JSON.stringify({
      params: {
        filter: { title: term },
      },
      locale: router.locale,
      defaultLocale: router.defaultLocale,
    }),
  })

  const results = await response.json()
}

Decision Points

Decision When Impact
Index fields Setup Query performance vs flexibility
Facet configuration Filtered search User experience vs complexity
API route vs direct Architecture Security vs simplicity

Common Mistakes

  • Querying search index directly from client — Exposes Drupal URL. WHY: Use API route to abstract backend.
  • Not passing locale to API route — Incorrect language results. WHY: Search API needs locale context.
  • Missing rate limiting — DoS vulnerability. WHY: Search is expensive, add rate limiting middleware.
  • Not indexing content — Empty results. WHY: Must run indexing cron or manual index after setup.

See Also

  • Fetching Content
  • Security Best Practices
  • drupal-jsonapi.md