jaspr_search 0.2.0 copy "jaspr_search: ^0.2.0" to clipboard
jaspr_search: ^0.2.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.

example/README.md

jaspr_search example #

jaspr_search has two halves that run in different places: a build-time indexer (plain Dart, runs anywhere) and a client-side search dialog (a Jaspr @client component, runs inside a Jaspr app). This directory has a runnable example of the first and a code sample of the second.

1. Build an index — runnable #

build_index_example.dart writes a couple of sample markdown pages to a temp directory, indexes them with buildSearchIndex, and runs a query against the result with searchIndex — the same ranking function the dialog uses in the browser. Run it directly:

dart run example/build_index_example.dart

For a real site, this is the shape of a tool/build_search_index.dart script:

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

void main(List<String> args) async {
  final build = await buildSearchIndex(Directory('content'));
  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);
    }
    return;
  }

  writeSearchIndex(build, output);
}

Or, for a site with no per-page grouping, skip the script entirely and use the bundled CLI: dart run jaspr_search. Run dart run jaspr_search --help for its flags.

2. Render the dialog — inside a Jaspr app #

SearchDialog is a @client component: it needs a Jaspr app to render into and a browser to interact with, so it isn't something a standalone example/ script can execute. In your site's header component:

import 'package:jaspr_search/jaspr_search.dart';

// wherever your header lives
const SearchDialog()

It fetches search-index.json (the file buildSearchIndex produces) the first time a reader opens it, and scores it in the browser with the same searchIndex function shown above. Its parameters are all String, bool and int — that is a hard requirement of @client, which serializes every constructor parameter across the server/client boundary.

Customising it #

For anything structural — your own trigger button, a translated empty state, a result row with a different layout — use SearchDialogView instead. It is the same dialog with no @client annotation, which is what lets it accept components and callbacks. Build it inside a @client wrapper of your own:

import 'package:jaspr/dom.dart'; // div
import 'package:jaspr/jaspr.dart';
import 'package:jaspr_search/jaspr_search.dart';

@client
class DocsSearch extends StatelessComponent {
  const DocsSearch({super.key});

  @override
  Component build(BuildContext context) => SearchDialogView(
    emptyState: (pageCount) => Component.text('Search $pageCount pages.'),
    resultContent: (hit, tokens) =>
        div(classes: 'my-row', highlightQuery(hit.title, tokens)),
  );
}

Then render const DocsSearch() where const SearchDialog() would have gone. See the package README for the full list of constructor options, the CSS classes and data-state hooks for styling, and why the two components exist.

4
likes
160
points
180
downloads

Documentation

API reference

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

MIT (license)

Dependencies

args, jaspr, jaspr_content, universal_web

More

Packages that depend on jaspr_search