Skip to main content
@mixpeek/search-js is a drop-in React component that connects to any published Mixpeek retriever. It provides a full search UI with keyboard shortcuts, filters, AI answers, and streaming results — no backend code required on your side.
npm install @mixpeek/search-js

Quick Start

1

Set up your search backend

Use the docs search quickstart to provision a complete pipeline in one API call, or create a retriever manually and publish it.
2

Install the widget

npm install @mixpeek/search-js
3

Add to your app

import { MixpeekSearch } from "@mixpeek/search-js";
import "@mixpeek/search-js/styles.css";

export default function App() {
  return (
    <MixpeekSearch
      projectKey="your-retriever-slug"
      placeholder="Search..."
      theme="auto"
      accentColor="#6366f1"
    />
  );
}
Users press Cmd+K (or Ctrl+K) to open the search modal. Results stream in from your retriever pipeline.

Props

PropTypeDefaultDescription
projectKeystringrequiredPublished retriever slug or ret_sk_* API key
placeholderstring"Search..."Input placeholder text
maxResultsnumber10Maximum results to show
theme"light" | "dark" | "auto""auto"Color theme
accentColorstring"#6366f1"Accent color (hex)
position"modal" | "inline""modal"Modal overlay or inline embed
keyboardShortcutbooleantrueEnable Cmd+K / Ctrl+K
showPoweredBybooleantrueShow “Search by Mixpeek” badge
enableAIAnswerbooleanfalseShow AI-generated answer with citations
enableShareLinksbooleanfalseEnable shareable search URLs
defaultOpenbooleanfalseStart with modal open
defaultFiltersRecord<string, unknown>-Default filter values on mount

Callbacks

PropTypeDescription
onSearch(query: string) => voidFires when a search is performed
onResultClick(result, index) => voidFires when a result is clicked
onZeroResults(query: string) => voidFires when no results are found
onFilterChange(filterInputs) => voidFires when filters change
transformResults(results[]) => results[]Transform results before rendering
renderResult(result, index) => ReactNodeCustom result renderer

CDN Usage (No Build Step)

For sites without a build system, load the widget via CDN:
<link rel="stylesheet" href="https://cdn.mixpeek.com/search/v1/mixpeek-search.css" />
<script
  src="https://cdn.mixpeek.com/search/v1/loader.js"
  data-project-key="your-retriever-slug"
  data-mount="search-container">
</script>

<div id="search-container"></div>

Filters

The widget includes built-in filter components for facets, ranges, and LLM-powered smart filtering.

Facet Filter

Single or multi-select dropdown:
<MixpeekSearch projectKey="my-search">
  <FacetFilter
    field="category"
    label="Category"
    options={[
      { label: "Electronics", value: "electronics" },
      { label: "Clothing", value: "clothing" },
    ]}
    multiple={true}
  />
</MixpeekSearch>

Range Filter

Numeric min/max slider:
<RangeFilter
  field="price"
  label="Price"
  min={0}
  max={1000}
  step={10}
  unit="$"
/>

Smart Filter (LLM-based)

Natural language filtering powered by the retriever’s LLM filter stage:
<SmartFilter
  label="Describe what you want"
  placeholder="e.g. red shoes under $50"
/>

AI Answers

Enable enableAIAnswer to show an LLM-generated answer with citations above search results. This requires an agent_search or rag_prepare stage in your retriever.
<MixpeekSearch
  projectKey="docs-search"
  enableAIAnswer={true}
/>

Hooks

Access search state from any child component:
import { useSearchKit } from "@mixpeek/search-js";

function MyComponent() {
  const {
    query,
    results,
    isLoading,
    aiAnswer,
    isOpen,
    open,
    close,
    search,
    filterInputs,
    setFilter,
    clearFilters,
    hasActiveFilters,
  } = useSearchKit();

  return <div>{results.length} results for "{query}"</div>;
}
Available hooks: useSearchKit, useSearch, useFilters, useKeyboardShortcut, useRecentSearches.

Setting Up the Backend

The widget needs a published retriever to connect to. There are two paths: Provision a complete search pipeline in one API call. This creates a namespace, bucket, collection (with web scraper + text embeddings), retriever, and published endpoint automatically:
curl -X POST https://api.mixpeek.com/v1/quickstart/docs-search \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "site_url": "https://docs.example.com",
    "site_name": "Example Docs"
  }'
The response includes a retriever slug and embed snippet ready to paste:
{
  "retriever_slug": "example-docs-search",
  "api_key": "ret_sk_...",
  "embed_snippet": "<MixpeekSearch projectKey=\"example-docs-search\" />"
}
Options: enable_code_search (default: true), enable_image_search (default: false), max_pages (default: 200), max_depth (default: 3).

Bootstrap CLI

The @mixpeek/react-searchkit package includes a CLI to scaffold a retriever with search, filter, and RAG stages:
npx mixpeek-bootstrap --api-key YOUR_API_KEY --slug my-site-search
This creates a retriever with feature_search, attribute_filter, and rag_prepare stages pre-configured.

Manual Setup

For full control, create each resource yourself:
1

Create a namespace and bucket

Set up storage and enable the feature extractors you need (guide).
2

Create a collection

Configure a collection with a feature extractor (e.g., text_extractor, web_scraper, multimodal_extractor) and trigger processing on your data (guide).
3

Create and publish a retriever

Build a retriever with the stages you need, then publish it to get a slug for the widget (guide).

Publishing a Retriever

Once you have a retriever, publish it to make it accessible to the widget:
from mixpeek import Mixpeek

client = Mixpeek(api_key="your-api-key")

result = client.retrievers.publish(
    retriever_id="ret_abc123",
    public_name="my-search",
)

print(result.public_url)  # https://mxp.co/r/my-search
The public_name becomes the projectKey you pass to the widget.

Authentication

The widget supports two authentication modes:
ModeprojectKey valueWhen to use
Public slug"my-retriever-slug"Public-facing search (no auth needed)
Scoped API key"ret_sk_..."Authenticated access with a retrieverSlug prop
// Public slug (most common)
<MixpeekSearch projectKey="my-retriever-slug" />

// Scoped API key
<MixpeekSearch projectKey="ret_sk_..." retrieverSlug="my-retriever-slug" />

Examples

The search widget is used on mixpeek.com as the site-wide search in the navigation bar, powered by @mixpeek/search-js with the mixpeek-blog-search retriever slug.
<MixpeekSearch
  projectKey="mixpeek-blog-search"
  placeholder="Search..."
  theme={isScrolled ? "light" : "dark"}
  accentColor="#6366f1"
  maxResults={10}
  showPoweredBy={true}
  keyboardShortcut={true}
  transformResults={(results) =>
    results.map((r) => ({
      id: r.document_id || r.id,
      title: r.title || r.page_title || "Mixpeek",
      content: r.content || r.text || "",
      page_url: r.page_url || r.url || null,
      image_url: r.image_url || null,
      score: r.score,
    }))
  }
/>

Exported Components

For building fully custom search experiences, the package exports composable sub-components:
ComponentDescription
SearchButtonStandalone search trigger button
SearchModalSearch modal container
SearchInputInput field
SearchResultsResults list
ResultCardIndividual result card
AIAnswerAI-generated answer panel
FilterPanelFilter container
FacetFilterSelect/multi-select filter
RangeFilterMin/max range slider
SmartFilterLLM-powered natural language filter
PoweredBy”Search by Mixpeek” badge
ShareLinkShareable search URL generator
ZeroResultsEmpty state placeholder
IntentCTAEnterprise CTA capture