StaticSearch bind module

(updated )

924 words, 5-minute read

The JavaScript bind module can automatically or programmatically attach StaticSearch functionality to HTML <input> and result elements. Use it in situations where you want to create a custom search widget but use StaticSearch functionality such as:

The bind module used by the web component so the processes are similar.

The following example automatically binds <input> and results elements using HTML alone:

HTML excerpt

<!-- include script once on your page -->
<script type="module" src="/search/staticsearch-bind.js"></script>

<!-- define input and result elements -->
<search>

  <input type="search" id="staticsearch_search">
  <div id="staticsearch_result"></div>

</search>

Input field attributes #

The <input> field must use the ID staticsearch_search but can have any other HTML attributes set.

StaticSearch presumes the name is q and checks its value on the querystring. You can set any other value, e.g.

HTML excerpt

<input type="search" id="staticsearch_search" name="query">

Search result attributes #

The results element must use the ID staticsearch_result but can set optional attributes:

attributedescription
minfound="<num>"only show pages containing at least this proportion of search words (0.0 to 1.0)
minscore="<num>"only show pages with total relevancy scores of this or above on results
maxresults="<num>"show up to this number of pages on the results
highlight="<any>"scroll to and highlight the first matching search terms

Search results provide a found value indicating the percentage of search words found on a page, e.g. two of four search words is 0.5.

Pages still appear in order of relevancy, but higher minfound values will reduce the number of results.

Set a highlight attribute to scroll to and highlight the first matching search terms on a results page. This uses text fragment links which can have issues:

  1. searching for “highlight” will return pages containing “highlighted” and “highlighter”, but they are not highlighted.

  2. A highlighted word could appear outside your main content, such as in a menu.

Overriding HTML templates #

You can change the HTML shown when displaying results using <template> elements.

Search results message #

When search results are available, you’ll see a message such as:

7 found for “web component”

It uses the HTML code:

HTML excerpt

<p part="resultmessage">
  <span part="resultcount"></span> found for
  <span part="searchterm"></span>&hellip;
</p>

You can override this using a <template> with an ID of staticsearch_resultmessage anywhere in your HTML page. You must set the part attributes "resultmessage", "resultcount", and "searchterm" as necessary, e.g.

HTML excerpt

<template id="staticsearch_resultmessage">

  <p part="resultmessage">
    StaticSearch found
    <span part="resultcount"></span> results
    for <span part="searchterm"></span>:
  </p>

</template>

Search result item #

An ordered list (<ol part="searchresult">) contains search results. Each page result uses the HTML:

HTML excerpt

<li part="item">
  <a part="link">
    <h2 part="title"></h2>
    <p part="meta">
      <time part="date"></time> &ndash;
      <span part="words">0</span> words
    </p>
    <p part="description"></p>
  </a>
</li>

You can override this using a <template> with an ID of staticsearch_item anywhere in your HTML page. Set the part attributes "item", "link", "title", meta, date, words, and "description" as necessary, e.g. show the title but no description, date, or word count in an <article>:

HTML excerpt

<template id="staticsearch_item">

  <li part="item">
    <article>
      <h2 part="title"><a part="link"></a></h2>
    </article>
  </li>

</template>

JavaScript binding #

You can programmatically bind StaticSearch functionality to <input> and result element using JavaScript. This may be useful if you want further control or you’re using a client-side framework to dynamically create content. Consider a page with the following HTML:

HTML excerpt

<search>

  <input type="search" id="mysearch">
  <div id="myresult"></div>

</search>

Bind the elements to StaticSearch using code such as:

JavaScript excerpt

import { staticSearchInput, staticSearchResult } from '/search/staticsearch-bind.js';

staticSearchInput( document.getElementById('mysearch') );
staticSearchResult( document.getElementById('myresult') );

Pass the <input> element to staticSearchInput(element).

Pass the result element and an optional options object to staticSearchResult(element, options). The option object properties:

option propertydescription
minFoundonly show pages containing at least this proportion of search words (default 0)
minScoreonly show pages with total relevancy scores of this or above on results (no minimum)
maxResultsshow up to this number of pages on the results (no maximum)
highlightscroll to and highlight the first matching search terms (default false)
resultElementthe outer list element (defaults to ol)
messageTemplatea DOM <template> configuring the results message
itemTemplatea DOM <template> configuring a result item

Example usage:

JavaScript excerpt

// custom results message
const messageTemplate = document.createElement('template');
messageTemplate.innerHTML = `
  <p part="resultmessage">
    <span part="resultcount">0</span> results found for
    <span part="searchterm"></span>:
  </p>
`;

// bind results element
staticSearchResult(
  document.getElementById('myresult'),
  {
    minFound: 0.5,    // at least half the search terms must be on a page
    minScore: 5,      // minimum relevancy score
    maxResults: 10,   // maximum number of results
    highlight: true,  // highlight search terms in page
    messageTemplate   // DOM <template> defined above
  }
);

Re-run the indexer #

Once you have added StaticSearch functionality to your static site’s templates, you should re-run the indexer to ensure word indexes are up-to-date.