VelinSearch 0.9.0 extension
Offline, fuzzy documentation and content search with grouped results, keyboard navigation, and highlighted matches.
Security: Result
href values pass through sanitizeSearchUrl. Highlights are escaped.
Overview
- Autocomplete from 2 characters
- Categories:
docs,components,api,examples - Fuzzy typo tolerance (e.g.
modla→velin-modal) - No page reload — live results panel
- Optional
registerSearchProvider()hook for app content
Web Component
<link rel="stylesheet" href="velinstyle.min.css">
<script type="module" src="velin-search.js"></script>
<velin-search
index="/dist/search-index.json"
categories="docs,components,api,examples"
min-chars="2"
fuzzy="0.2"
placeholder="Search…">
</velin-search>
Declarative binding:
<input velin-search-input data-search-index="../search-index.json">
<div velin-search-results></div>
JavaScript API
import { velinSearch, createSearch, registerSearchProvider } from '@birdapi/velinstyle/search';
await velinSearch.loadIndex('/search-index.json');
const search = createSearch({ worker: true });
await search.loadIndex('/search-index.json');
const { results, groups } = await search.query('tokens', {
minChars: 2,
fuzzy: 0.2,
categories: ['docs', 'components'],
limit: 12,
});
Build index
# Framework repo
npx velinstyle search index --out dist/search-index.json
# Included when generating docs
npm run docs:generate
Sources: generated Markdown (components, tokens, utilities, CLI), samples HTML, cli-manifest.json.
Schema: examples/search-index.schema.json in the framework package.
Custom providers
registerSearchProvider('cms', async () => {
const res = await fetch('/api/search-docs.json');
return res.json();
});
await velinSearch.refreshProviders();
This documentation site
The header #docSearch field uses docs/doc-search.js (ES module) importing core/search from the sibling velinstyle repo. Rebuild the merged index:
python tools/build-search-index.py
python tools/sync-sidebar.py