The System Halted

Search Architecture

Search Architecture

This site has two search entry points that share the same index:

  • The sitewide search overlay (opened from the masthead or by pressing “/”).
  • The legacy command-line UI at /webcmd/.

Both use a build-time index generated by Jekyll in assets/js/webcmd.js.

Data flow diagram

Jekyll build
  |
  v
assets/js/webcmd.js (Liquid builds siteDocs + siteIndex)
  |                     |
  |                     +--> window.siteDocs, window.siteIndex
  |
  +--> /webcmd/ UI (cmd_find uses siteIndex/siteDocs)
  |
  +--> Site UI overlay (assets/js/script.js uses siteIndex/siteDocs)

Build-time index (Jekyll)

assets/js/webcmd.js has front matter so Jekyll processes Liquid inside the JavaScript file:

---
---

During the build, the script loops over site.collections and builds siteDocs:

  • Includes every coll.docs item with output != false.
  • For each doc, it stores:
    • id: sequential integer.
    • title: doc.title.
    • layout: doc.layout.
    • content: doc.content | strip_html.
    • link: doc.url | relative_url.
    • snippet: doc.content | strip_html | truncate: 140.

It then builds an elasticlunr index with fields title, layout, and content and saves it to window.siteIndex.

Runtime search overlay (site UI)

Markup lives in _layouts/default.html:

  • #search-toggle opens the overlay.
  • #search-overlay contains #search-input, #search-results, and #search-status.
  • data-webcmd-url points to /webcmd/ for fallbacks.

Logic lives in assets/js/script.js:

  • On input, renderResults() searches the index with expand: true.
  • If window.siteIndex is missing, it builds a new index from window.siteDocs.
  • If elasticlunr returns zero results, it falls back to a substring scan across title and content.
  • Results are capped at 12 and show title, layout, and snippet.
  • Escape closes the overlay; “/” opens it (unless focused in an input/textarea).

The /webcmd/ page includes assets/js/webcmd.js and exposes:

find <query>

Key behavior in assets/js/webcmd.js:

  • ensureSiteIndex() builds the index if it is missing.
  • cmd_find() searches and falls back to a substring scan when needed.
  • Results are capped at 10 and display doc.snippet.

Scope of indexed content

  • Only documents in site.collections with output != false are indexed.
  • Standalone pages (e.g., about.md, index.html) are not indexed unless they live in a collection.
  • Drafts are included only when Jekyll is run with --drafts.

Extension points

  • Include pages: update assets/js/webcmd.js to also add site.pages.
  • Add fields: include categories, tags, or description in siteDocs and index them in elasticlunr.
  • Adjust snippets: change the truncate length or use description when present.
  • UI tweaks: update the overlay styles in assets/css/nord.css under the search section.

Troubleshooting

  • “Search index not available”: ensure assets/js/elasticlunr.min.js and assets/js/webcmd.js load in _layouts/default.html.
  • Missing documents: verify the collection is output: true and the doc has front matter.
  • Stale results: rebuild the site; the index is generated at build time.