Setup

Start with <Searchbar />. It is the fastest path for most apps. Move to primitives only when you need custom UI.

Etoile searchbar


1) Drop-in Searchbar

"use client";

import { useRouter } from "next/navigation";
import "@etoile-dev/react/styles.css";
import { Searchbar } from "@etoile-dev/react";

export default function App() {
const router = useRouter();

return (
  <Searchbar
    apiKey={process.env.NEXT_PUBLIC_ETOILE_PUBLIC_KEY}
    collections={["paintings", "artists"]}
    onSelectResult={(result) => router.push(`/work/${result.external_id}`)}
  />
);
}

Use your public key in client-side React code.


2) Command palette

"use client";

import { useRouter } from "next/navigation";
import "@etoile-dev/react/styles.css";
import { SearchModal } from "@etoile-dev/react";

export default function App() {
const router = useRouter();

return (
  <SearchModal
    apiKey={process.env.NEXT_PUBLIC_ETOILE_PUBLIC_KEY}
    collections={["paintings", "artists"]}
    onSelectResult={(result) => router.push(`/work/${result.external_id}`)}
  />
);
}

3) Headless primitives

Use primitives when you want full control over markup and styles. Searchbar.Results keeps the result mapping simple.

"use client";

import { useState } from "react";
import { Searchbar, useEtoileSearch } from "@etoile-dev/react";

export default function CustomSearch() {
const [query, setQuery] = useState("");

const { results, isLoading, error } = useEtoileSearch({
  apiKey: process.env.NEXT_PUBLIC_ETOILE_PUBLIC_KEY,
  collections: ["paintings", "artists"],
  query,
});

return (
  <Searchbar.Root
    search={query}
    onSearchChange={setQuery}
    isLoading={isLoading}
    error={error}
  >
    <Searchbar.Input placeholder="Search..." />
    <Searchbar.List>
      <Searchbar.Results
        results={results}
        renderItem={(result) => (
          <Searchbar.Item value={result.external_id} label={result.title}>
            {result.title}
          </Searchbar.Item>
        )}
      />
    </Searchbar.List>
  </Searchbar.Root>
);
}

Searchbar props

ParameterTypeDescription
apiKeyrequiredstringYour public API key.
collectionsrequiredstring[]Collections to search.
limitnumberMax results (default: 10).
offsetnumberPagination offset (default: 0).
debounceMsnumberDebounce delay in ms (default: 100).
placeholderstringInput placeholder (default: "Search…").
filtersSearchFilter[]Apply explicit metadata filters.
autoFiltersbooleanLet AI extract filters from the query.
renderItem(result: SearchResult) => ReactNodeCustom item renderer.
onSelect(value: string) => voidCalled with selected external_id.
onSelectResult(result: SearchResult) => voidCalled with the full selected result. Recommended for routing.
hotkeystringGlobal shortcut, for example "/" or "mod+k".
classNamestringExtra class names. The wrapper always includes "etoile-search".

Searchbar also supports non-state behavior props from Searchbar.Root, such as open, defaultOpen, onOpenChange, and hotkeyBehavior.


Resources


Next