Basker Docs

Search

Query published content across your site for search-as-you-type and search results pages

The search endpoint runs a full-text query across the published content on your site and returns ranked matches. Use it to build search-as-you-type boxes, a dedicated results page, or any widget that needs to find content from the browser.

Matching is both exact and fuzzy, so queries that are close but not exact still return useful results. Basker automatically applies editor-configured boosts and synonyms to the ranking.

GET {your-domain}/api/search?q={query}

Unlike the content endpoints, search does not accept the .json suffix. Always call the bare /api/search path.

Query parameters

ParameterTypeDefaultDescription
qstringNoneThe search query. Required. A missing query returns a 400.
collectionstring(all types)Restrict results to one or more content types. Separate multiple values with commas. Valid values are pages, posts, events, and people. Omit to search all types. An unrecognized value returns a 400.

Results always come back in the language of the request. Search uses the locale that the request URL sets.

Response

A docs array of ranked matches plus list metadata. Each item carries a collectionType field identifying which content type it matched, so you can group or filter results by type on the client.

{
  "docs": [
    {
      "id": "000000000000000000000002",
      "collectionType": "events",
      "title": "Moonclock",
      "slug": "moonclock",
      "url": "/events/moonclock"
    },
    {
      "id": "000000000000000000000004",
      "collectionType": "posts",
      "title": "How Moonclock was made",
      "slug": "making-moonclock",
      "url": "/blogs/remarkable-theatre-news/posts/making-moonclock"
    }
  ],
  "totalDocs": 2,
  "limit": 200,
  "totalPages": 1,
  "page": 1,
  "pagingCounter": 1,
  "hasPrevPage": false,
  "hasNextPage": false,
  "prevPage": null,
  "nextPage": null
}

Search returns the full ranked set, up to 200 results, in a single response. It does not paginate the results. The exact fields on each result depend on the content type that matched. Every result always includes an id, a collectionType, a title, and a link you can render.

Examples

Search as the visitor types:

async function search(query) {
  if (!query) return [];
  const res = await fetch(`/api/search?q=${encodeURIComponent(query)}`);
  const { docs } = await res.json();
  return docs;
}

Group results by content type for a tabbed results page:

const { docs } = await (await fetch(`/api/search?q=${encodeURIComponent(query)}`)).json();

const byType = docs.reduce((groups, result) => {
  (groups[result.collectionType] ??= []).push(result);
  return groups;
}, {});
// byType.events, byType.posts, byType.people, …

Caching

Search responses are cacheable at the edge. Because queries vary per visitor, popular queries benefit from caching while long-tail queries fall through to a fresh response. Avoid appending request-uniqueness parameters (cache-busters, timestamps) to the URL unless you genuinely need to bypass the cache.

See also

On this page