jaspr_search 0.1.0 copy "jaspr_search: ^0.1.0" to clipboard
jaspr_search: ^0.1.0 copied to clipboard

Client-side full-text search for static Jaspr sites — a search dialog component plus a build-time indexer, with no backend to query.

jaspr_search #

Client-side full-text search for static Jaspr sites built with jaspr_content — a search dialog component plus a build-time indexer. No backend, no crawler, no API key: the index is a JSON file your site already ships, fetched once and scored in the browser.

Extracted from two documentation sites (Zonai, Revali) that had independently built and then separately bug-fixed the same thing.

What you get #

  • SearchDialog — a @client component: a trigger button plus a modal dialog. Opens on click, ⌘K/Ctrl+K, or /. Arrow keys move the selection, Enter navigates, Esc closes. Ships with default styles that respect jaspr_content's theme colors; override or opt out.
  • jaspr_search CLI / buildSearchIndex — walks a content/ directory of markdown files, splits each page on its headings, and produces the doc list that becomes search-index.json.
  • searchIndex — the ranking function both sides use: every query word must match somewhere in a section (AND, not OR), with score boosts for title/heading/URL matches and whole-phrase hits.

Usage #

1. Build the index #

For a site with no per-page grouping, the bundled CLI is enough:

dart run jaspr_search --content content --output web/search-index.json

Both flags default to those paths, so dart run jaspr_search alone works for the common layout. Add --check for CI, so a content change that forgot to regenerate the index fails the build instead of silently going stale:

dart run jaspr_search --check

Run dart run jaspr_search --help for the rest of the flags (--max-section-length among them).

If your site groups pages under sections and wants that label shown on each result, the CLI can't express it — groupFor is a Dart closure reaching into the site's own navigation code, not something a flag can carry. Write a tiny entrypoint instead:

// tool/build_search_index.dart
import 'dart:io';
import 'package:jaspr_search/builder.dart';

void main(List<String> args) async {
  final build = await buildSearchIndex(
    Directory('content'),
    groupFor: (route) => sectionOf(route)?.title ?? '',
  );
  final output = File('web/search-index.json');

  if (args.contains('--check')) {
    if (!searchIndexIsCurrent(build, output)) {
      stderr.writeln('web/search-index.json is stale. Run: dart run tool/build_search_index.dart');
      exit(1);
    }
    stdout.writeln('Search index is up to date (${build.docs.length} pages).');
    return;
  }

  writeSearchIndex(build, output);
  stdout.writeln('Wrote ${output.path} — ${build.docs.length} pages, ${build.sectionCount} sections.');
}

See the doc comment on buildSearchIndex for the rest of the hooks (routeOf, titleFor, descriptionFor, compare).

Either way, run it before jaspr build / jaspr serve.

2. Render the dialog #

import 'package:jaspr_search/jaspr_search.dart';

// wherever your header lives
const SearchDialog()

Customize text, the index path, or the result caps through its constructor — see the doc comment on SearchDialog for the full list. Set includeDefaultStyles: false to supply your own CSS for the jaspr-search-* classes instead.

Why client-side #

Both source sites are static, deployed to GitHub Pages — there is nothing to query server-side, and one of them dropped an Algolia DocSearch integration for this (a crawler, an API key in the config, and results that lagged a deploy). The index is fetched once, on first use, so it costs nothing for readers who never search.

4
likes
0
points
180
downloads

Publisher

verified publishermrgnhnt.com

Weekly Downloads

Client-side full-text search for static Jaspr sites — a search dialog component plus a build-time indexer, with no backend to query.

Repository (GitHub)
View/report issues

Topics

#jaspr #search #static-site #documentation

License

unknown (license)

Dependencies

args, jaspr, jaspr_content, universal_web

More

Packages that depend on jaspr_search