SDKs

Browser SDK

@findlane/browser searches an index from the browser with its public ID. It has no dependencies and is about 1 KB.

Install

npm install @findlane/browser

Create a client

import { SearchBrowserClient } from "@findlane/browser"

const client = new SearchBrowserClient({ publicId: "pub_your_public_id" })
Option
publicIdThe index's public ID, from its Public access page.
baseUrlThe API to call. Leave it out to use Findlane's hosted API.
fetchA fetch implementation to use instead of the global one, for tests or instrumentation.

Browser search works from the index's allowed origins; see Security.

search(request, options)

type Product = {
  objectID: string
  title: string
  brand: { name: string }
  price: number
  image: string
}

const results = await client.search<Product>(
  { q: "trail shoe", facets: ["brand.name"], limit: 24, highlight: true },
  { signal: controller.signal }
)

The type parameter types each hit's record. options.signal cancels the request.

Request

FieldType
qstringThe query, up to 200 characters.
filtersobjectField values to keep: a value, { in: [...] }, or { gte, lte } for numbers. See Filters.
facetsstring[]Facet fields to count values for, up to eight.
sortstringA sort ID from the index's settings, or "relevance".
limitnumberHits to return, 1 to 50. Default 20.
offsetnumberHits to skip, up to 1,000.
countMode"page" or "exact""exact" counts every match in total.
facetMode"page" or "exact""exact" counts facet values across every match.
highlightboolean or { preTag, postTag }Mark matched words in highlights.
attributesToRetrievestring[]Return only these fields.

Response

FieldType
hits{ id, score, record, highlights? }[]The matching records. score is null without a query or when sorting by a field.
totalnumberMatches: a lower bound when totalRelation is "gte".
totalRelation"eq" or "gte"Whether total is exact.
hasMorebooleanWhether there are hits after this page.
facetsRecord<string, Record<string, number>>Counts per value of each requested facet.
sortstringThe sort used.
tookMsnumberTime the search took on the server.

Errors

A failed request throws a FindlaneError with the HTTP status and the API's message:

import { FindlaneError } from "@findlane/browser"

try {
  await client.search({ q })
} catch (error) {
  if (error instanceof FindlaneError && error.status === 429)
    showMessage("Too many searches, try again shortly")
  else throw error
}
StatusMeaning
400The request isn't valid, such as an unknown facet or sort. The message says why.
402The workspace has used the searches its plan includes this month.
403This origin isn't allowed, or the public ID doesn't exist.
429Too many searches: 240 a minute per visitor, or 6,000 per index.

A cancelled request rejects with the AbortError from fetch.

Without a bundler

The package is a standard ES module, so a page can load it from a CDN that serves npm packages:

<script type="module">
  import { SearchBrowserClient } from "https://esm.sh/@findlane/browser@0"

  const client = new SearchBrowserClient({ publicId: "pub_your_public_id" })
  const { hits } = await client.search({ q: "jacket" })
  console.log(hits)
</script>