The client
Call the Query API from any storefront with typed requests and answers, and read and write a listing's URL.
@orbsearch/client calls the Query API with typed requests and answers. It needs no framework, and the React components build on it:
import { } from "@orbsearch/client";
export const = ({ : "http://127.0.0.1:7800" });
const = await .("graues Sofa");
const = await .({ : "SOFA-ASKA-2" });
const = await .("/wohnen/sofas?color=grey");The calls search for "graues Sofa" (grey sofa), fetch one sofa and ask what the sofa page /wohnen/sofas (wohnen: living) with grey chosen is. Hover a call to read what it answers.
The packages are not on npm yet. A shop inside this repository's pnpm workspace depends on them as workspace:*, as the demo storefront in apps/demo does, and its bundler compiles their TypeScript source:
{
"dependencies": {
"@orbsearch/client": "workspace:*",
"@orbsearch/react": "workspace:*"
}
}The calls
Each call is one request. The second argument is the request without its text, with filters in the shape a listing's URL holds, and the third cancels the call when the shopper moves on:
const = new ();
const = await .(
"",
{ : "category_page", : "wohnen/sofas", : { : ["grey"] }, : "price_asc" },
{ : . },
);querysearches or browses a category (Search and browse).productfetches one product byidorurl, ornullwhen the channel sells none (Product pages).resolvesays what one of the merchant's URLs is: a listing with its results, a product, a redirect or nothing (URLs and redirects).facetscounts named facets in full, without products, for a facet that loads when opened.suggestionsreturns the store a search box runs on (Autocomplete).
In the browser, registerAgentTools offers the same client to agents as WebMCP tools (Agents).
Reference: POST /v1/search · GET /v1/product · GET /v1/resolve
One client per page load
A client's searches name one page view, which Insights counts queries by. Make one client per page the shopper loads: once in the browser, and once per request on a server, with the shopper's User-Agent:
import { } from "@orbsearch/client";
export function (: ) {
const = ..("user-agent");
return ({ : "http://127.0.0.1:7800", ...( && { }) });
}The user agent tells a crawler from a shopper, which the server's own would hide. The page view lives in memory only: pass the server's to the browser's client as pageView, and a page load counts once. traffic: "test" or "bench" marks searches the merchant's reports leave out.
Reference: page_view · traffic
Errors
A call the Query API refuses throws a SearchError, whose problem says why in words a person can read:
import { , } from "@orbsearch/client";
const = ({ : "http://127.0.0.1:7800" });
try {
await .("sofa", { : "cheapest" });
} catch () {
if (!( instanceof )) throw ;
.(.., ..);
}- 400 means the request cannot be answered as sent, such as the unknown sort above, and
problem.violationsnames each wrong field. - 503 means nothing is searchable yet or the engine is unreachable. Offer the shopper the same page again.
Reference: Problems
Types from the contract
Every request, answer, release file and catalog entity is a type generated from the contract, such as SearchResponse, FacetResult or PageResponse. Hover one to read its fields:
import type { } from "@orbsearch/client";
export function (: ): string[] {
return (. ?? []).(() => ..(() => .));
}The contract's values come as constants, such as SEARCH_PATH, RELEVANCE_SORT and LATENCY_BUDGETS. Mind one name: Product from the client is a product page's product, Product from @orbsearch/react a tile's.
Reference: Query API
A listing's URL
A search, category or brand page keeps its whole state in its URL, so a link, the back button and a crawler see what the shopper sees. listingHref writes it:
import { } from "@orbsearch/client";
("/suche", {
: "sofa",
: { : ["grey", "green"], : { : 100, : 300 }, : true },
: "price_asc",
: 2,
});
// "/suche?q=sofa&color=green&color=grey&on_sale=1&price.gte=100&price.lte=300&sort=price_asc&page=2"Fields stand in alphabetical order and values sorted, so one choice has one URL. Leave page out after a change of filters or sort, and the page starts at 1. Three helpers read a listing back:
listingOf(page)reads it fromresolve's answer, since the merchant may rename parameters.keptParams(listing)holds what a form that changes filters or sort keeps as hidden fields, such asq.filtersOf(url, facets)reads filters for facets you hold yourself. It needs the facets, sinceseats=1is a value whereon_sale=1is a toggle.
The helpers write each parameter by its code, as a release without parameters in routes.json does; URLs and redirects says what renamed parameters change.
Reference: routes.json
Next
- React components: the search box and the pages built on this client.
- Your storefront: a whole shop on the client in a few minutes.
- Clicks and views: report what shoppers open and see.