Skip to main content
Ceisium logo Ceisium

UI Components

Install search UI patterns and wire them to a Ceisium project.

Browse docs

UI components give visitors a search surface backed by either a restricted Browser/public key or your own server route.

Component patterns

PatternUse it when
Command paletteUsers expect keyboard search with / or a shortcut.
Inline searchA docs page needs a visible input and result list.
Search barA compact bar should open a modal when clicked.
Search modalYou want a SigNoz-style overlay with a search input and results.

Direct browser setup

Create a Browser/public key, configure its allowed origins and result URL prefixes, and expose it as CEISIUM_PUBLIC_SEARCH_KEY in your client configuration.

TS
const response = await fetch("https://api.ceisium.com/v1/search", {  method: "POST",  headers: {    Authorization: `Bearer ${CEISIUM_PUBLIC_SEARCH_KEY}`,    "Content-Type": "application/json",  },  body: JSON.stringify({    project_id: CEISIUM_PROJECT_ID,    query,    top_k: 8,    path_prefix: "https://signoz.io/docs/",  }),});

Server route alternative

If you use a Server key, keep it on your backend and have the component call your route.

TS
export async function POST(request: Request) {  const { query, top_k = 8 } = await request.json();  const response = await fetch("https://api.ceisium.com/v1/search", {    method: "POST",    headers: {      Authorization: `Bearer ${process.env.CEISIUM_SEARCH_KEY}`,      "Content-Type": "application/json",    },    body: JSON.stringify({      project_id: process.env.CEISIUM_PROJECT_ID,      query,      top_k,    }),  });  return Response.json(await response.json());}

Client config

Keep the config small:

TS
{  placeholder: "Search docs...",  shortcut: "/",  limit: 8,  debounceMs: 200,  emptyMessage: "No results found."}

For SigNoz, useful preview queries are:

TXT
OpenTelemetry Python instrumentationsend traceslogs exploreralerts

Result behavior

Each result should show:

  • Page title.
  • Short snippet.
  • Canonical URL or path.
  • Click handler that navigates to the result.

Keep result lists scrollable so long docs sites do not make the modal grow past the viewport.

Latest request wins

During fast typing, an older request can finish after a newer request. Debouncing reduces request volume, but it does not guarantee response order. Cancel superseded work and only let the newest request update the UI.

TS
let activeController: AbortController | null = null;let requestVersion = 0;async function search(query: string) {  const version = ++requestVersion;  activeController?.abort();  const controller = new AbortController();  activeController = controller;  try {    const response = await fetch("https://api.ceisium.com/v1/search", {      method: "POST",      signal: controller.signal,      headers: {        Authorization: `Bearer ${CEISIUM_PUBLIC_SEARCH_KEY}`,        "Content-Type": "application/json",      },      body: JSON.stringify({        project_id: CEISIUM_PROJECT_ID,        query,        top_k: 8,      }),    });    const data = await response.json();    if (version !== requestVersion) return;    renderResults(data.results);  } catch (error) {    if (error instanceof DOMException && error.name === "AbortError") return;    if (version === requestVersion) renderError();  }}

Ceisium’s built-in component previews already apply this guard. Add it when you call the raw Search API from a custom typeahead client.

Styling

Use your app theme tokens for borders, background, text, and focus states. Avoid hardcoded colors in the component.