What it does

Client-side fuzzy search over the article registry. No server round-trip, no embeddings. Implemented by useSearch (KB/src/hooks/useSearch.ts).

Library

fuse.js@^7.0.0. Imported as default in the hook (KB/src/hooks/useSearch.ts:2).

Index

Built once per articles array via useEffect (KB/src/hooks/useSearch.ts:28–30):

const FUSE_OPTIONS = {
  keys: [
    { name: "title",   weight: 0.5 },
    { name: "summary", weight: 0.3 },
    { name: "tags",    weight: 0.2 },
  ],
  threshold: 0.35,
  minMatchCharLength: 2,
  shouldSort: true,
  includeScore: true,
};

content (full article body) is not indexed. Tag matches outweigh body matches by default but body matches simply do not exist.

Behaviour

  • Typing fewer than 2 characters returns [] (KB/src/hooks/useSearch.ts:38–41).
  • Results update on every keystroke via a useEffect watching searchTerm.
  • clearSearch() resets both the term and the result list.

UI integration

<Sidebar> owns the search input (KB/src/components/Sidebar.tsx:188–237). Results render inside a popover-style <SearchResults> panel (KB/src/components/SearchResults.tsx) docked under the input.

showResults state in <Sidebar> is searchTerm.length >= 2. Click-outside dismisses the panel via a global mousedown listener (KB/src/components/Sidebar.tsx:124–132).

Selecting a result calls onSelect(article) from <App>, then clearSearch() resets the input.

Result rendering

<SearchResults> shows: article title, applicability emoji (🇸🇪 / 🇪🇺 / 🌍), category pill, first two tags as pills, and the summary line-clamped to 2 lines. Empty result state shows “No articles found for “”“.

Gotchas

  • No content search. Searching “Bisnode” finds entries that mention it in summary or tags, but not entries whose body discusses it without naming it in metadata. Adding { name: "content.content", weight: 0.1 } would require flattening the nested KBSection[].
  • Type usage. Fuse.IFuseOptions is referenced as a namespace member (KB/src/hooks/useSearch.ts:5). In fuse.js v7 the type is exported flat (IFuseOptions). This may emit a TS error under strict depending on @types resolution; the runtime works regardless.
  • Re-index on every articles reference change. useEffect dependency is the array reference. Since allArticles is module-level (KB/src/kb/index.ts), the reference is stable and reindexing happens once.

See also

KB Architecture, KB UI Components, KB Content Index.

See also