All repositories

astro-lunr

License

Lunr integration for Astro; client-side search for statically hosted pages.

2022-05-14 17:06 #1: fixed base path replacement problem
Siver K. Volle 3f44311
2022-05-14 17:06 #1: fixed base path replacement problem master Siver K. Volle 3f44311
2022-05-01 13:57 Fixed problem with import.meta.env when proper npm-module Siver K. Volle 00a915f
2022-04-18 20:31 add demo-link to readme Siver K. Volle d930b81
2022-04-18 19:51 initial steps to turn astro-lunr into its own repo Siver K. Volle 9983ab3
2022-04-18 18:39 better lunr in dev-mode; better file diffs Siver K. Volle 182546c
2022-04-16 00:25 Included readme and licenses; made the plugins into npm-modules; removed more dead-links and ui/ux-bugs Siver K. Volle 077a354
2022-04-15 17:21 Multi-repo support; refactored astro-git and astro-lunr into independent plugins Siver K. Volle adfedbe
astro-lunr / README.md
112 lines (83 sloc) | 4.4 KB

astro-lunr

Lunr integration for Astro; client-side search for statically hosted pages.

Demo through the search-bar for astro-git-view hosted on Github Pages

See example of usage in astro-git-view’s source code

Usage

import { defineConfig } from 'astro/config';
import astroLunr from 'astro-lunr/plugin.mjs';
export default defineConfig({
  integrations: [
    astroLunr({})
  ]
});

Config

pathFilter, subDir, documentFilter, initialize, mapDocument, verbose

Config fieldTypeValue
subDirstringSubdirectory to store the created idx.json and docs.json files.
pathFilter(string) => booleanFilter for paths that should be searched for <lunr-document/>-elements
documentFilter(string) => booleanFilter for documents should be included in the final index, after they are found by searching the pre-generated pages
initialize(lunr.Builder, lunr) => voidLunr-specific setup. E.g. fields to index and pipeline-adjustments
mapDocument(Object) => ObjectTransform the documents before storing them in docs.json
verbosebooleanDebug log

Example from astro-git-view

astroLunr({
  subDir: "lunr",
  pathFilter: (pathname) => {
    return pathname.match(/\w+\/tree\//);
  },
  documentFilter: (doc) => {
    return doc.ref === "master" && !doc.canonicalUrl.includes("package-lock.json");
  },
  initialize: (builder, lunr) => {
    lunr.tokenizer.separator = /[^\w]+/;
    builder.pipeline.reset();
    builder.searchPipeline.reset();
    builder.field("ref", {boost: 0.01});
    builder.field("oid", {boost: 0.01});
    builder.field("path", {boost: 0.1});
    builder.field("name", {boost: 10});
    builder.field("content");
    builder.metadataWhitelist = ["position"];
  },
  mapDocument: (doc) => doc,
  verbose: false
})

Indexing documents

Indexing is done automatically during build-time, by searching the genereated pages for the <lunr-document/>-element on any of the generated pages. These elements are removed from the final version of the build-output, and therefore only affects the two generated index-files idx.json and docs.json.

Multiple indexes are supported by supplying the index-attribute to the <lunr-document/>-elements. Each index will create their own idx.json/docs.json pair.

Example from astro-git-view

<lunr-document index={repo.getName()}>
    <lunr-field name="repo" value={repo.getName()}/>
    <lunr-field name="ref" value={ref}/>
    <lunr-field name="path" value={path}/>
    <lunr-field name="base" value={path.split("/").slice(0,-1).join("/")}/>
    <lunr-field name="name" value={name}/>
    <lunr-field name="oid" value={oid}/>
    <lunr-field name="type" value={"blob"}/>
    <lunr-field name="extension" value={name.split(".").pop()}/>
    <lunr-text name="content">{content}</lunr-text>
</lunr-document>

Searching

astro-lunr gives two functions to search search and enrich. async search(query, index) loads and deserializes the idx.json file, performs the search, and returns the hits from lunr. async enrich(hits, index) loads the docs.json file and enriches the result from lunr with the documents that were matches.

As the two json-files often can be megabytes in size, it is recommended to not

Example

import initializeLunr from 'astro-lunr/client/lunr.js';

const {search, enrich} = initializeLunr({lunrDir: "./lunr"})

search("query", "index")
  .then(enrich)
  .then((result) => result.forEach(
    ({hit, doc}) => console.log(hit, doc)))

Searching in Dev-mode

Due to the nature of indexing, to properly search in dev-mode, one needs to first build the pages at least once to create the index

Searching in SSR-mode

To properly search files that are not usually genereated in the build-step, you would need to have a separate build-step that includes all pages that might be generated.

A potential future solution would be to include a way to index using static paths that are completely separate from the usual page-generation.