@growth-labs/search
v0.3.1
Published
Search integration using Cloudflare AI Search. Provides search dialog component (Cmd+K), API route, result ranking, and search analytics events.
Downloads
626
Readme
@growth-labs/search
Search integration using Cloudflare AI Search. Provides search dialog component (Cmd+K), API route, result ranking, and search analytics events.
Config
import search from '@growth-labs/search'
search({
instanceName: 'fedweek-search',
aiBinding: 'AI', // Wrangler binding name (default)
maxResults: 10,
strings: {
placeholder: 'Search FEDweek...',
},
admin: {
enabled: true,
// Serialized with Function.prototype.toString(); keep self-contained.
isAdmin: ({ request }) => request.headers.get('x-admin-key') === 'expected',
},
})What It Injects
Route: GET /api/search — search query endpoint with Zod validation. The route reads the configured AI binding through cloudflare:workers env bindings in Cloudflare Workers.
Admin routes: when admin.enabled: true, injects POST /api/search/admin/reindex and POST /api/search/admin/reindex/bulk. They validate package search documents, write Markdown objects to the configured R2 binding, store premium/gated metadata as R2 custom metadata, and can trigger the documented Cloudflare AI Search sync job REST endpoint.
Component: <SearchDialog /> — Cmd+K triggered, vanilla JS (no framework dependency). Accessible, keyboard-navigable.
Headless utility: createHeadlessSearchController() from @growth-labs/search/utils provides open/close keyboard handling, debounced and abortable searches, loading/error/empty/result state, and ARIA props for custom UIs.
Wrangler Bindings
[ai]
binding = "AI"
[[r2_buckets]]
binding = "SEARCH_INDEX_BUCKET"
bucket_name = "fronts-search-index"AI Search must be configured per-site in the Cloudflare dashboard. If you override aiBinding, the wrangler binding name must match it.
Admin R2 sync uses CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_API_TOKEN when admin.triggerSync is true. The API token needs Cloudflare AI Search edit/run permissions.
Serialized Callbacks
isGated and admin isAdmin are serialized into the virtual config with Function.prototype.toString(). Keep them self-contained: they cannot rely on closure variables, imported helpers, or runtime-only values.
Analytics Integration
Optional. If @growth-labs/analytics installed, emits:
search_performed— with query + result countsearch_no_results— when zero results returned
Key Patterns
- Virtual module:
virtual:growth-labs/search/config .astrocomponent files ship as source, not compiled- Zod validation on search input
- Results ranked by Cloudflare AI Search — package doesn't re-rank
