inserted heading 8. search
inserted paragraph zola can generate a client-side search index using elasticlu...
inserted paragraph enable in config.toml:
inserted paragraph this produces two files in the build output:
inserted list item elasticlunr.min.js — the search library
inserted list item search_index.en.js — the index data (sets window.searchIndex...
inserted paragraph create a search page:
inserted paragraph content/search.md:
inserted code block +++
title = "search"
template = "search.html"
+++
inserted paragraph templates/search.html:
inserted code block {% extends "base.html" %}
{% block content %}
<h1>search</h1...
inserted paragraph live example: docs.sublimated.com/zola/search/
inserted list item client-side search (elasticlunr.js)
modified code block build_search_index = true
M /docs/undefined +64 -1
256 unmodified lines257
258- `?w=128` — resize to 128px wide (keeps aspect ratio)259- works on any image served through sublimated CDN260
261## 8. search262
263zola can generate a client-side search index using [elasticlunr.js](http://elasticlunr.com/).264
265enable in config.toml:266```toml267build_search_index = true268```269
270this produces two files in the build output:271- `elasticlunr.min.js` — the search library272- `search_index.en.js` — the index data (sets `window.searchIndex`)273
274create a search page:275
276`content/search.md`:277```md278+++279title = "search"280template = "search.html"281+++282```283
284`templates/search.html`:285```html286{% extends "base.html" %}287{% block content %}288<h1>search</h1>289<input type="text" id="search-input" placeholder="type to search..." autofocus />290<p id="search-meta"></p>291<ul id="search-results"></ul>292
293<script src="{{ config.base_url }}elasticlunr.min.js"></script>294<script src="{{ config.base_url }}search_index.en.js"></script>295<script>296(function () {297 var index = elasticlunr.Index.load(window.searchIndex);298 var input = document.getElementById("search-input");299 var results = document.getElementById("search-results");300 var meta = document.getElementById("search-meta");301
302 input.addEventListener("input", function () {303 var query = input.value.trim();304 results.innerHTML = "";305 if (!query) { meta.textContent = ""; return; }306 var hits = index.search(query, { expand: true });307 meta.textContent = hits.length + " result" + (hits.length !== 1 ? "s" : "");308 for (var i = 0; i < hits.length; i++) {309 var doc = index.documentStore.getDoc(hits[i].ref);310 var li = document.createElement("li");311 var body = (doc.body || "").substring(0, 200);312 li.innerHTML = '<a href="' + doc.id + '">' + (doc.title || doc.id) + '</a>'313 + '<p>' + body + (body.length >= 200 ? '...' : '') + '</p>';314 results.appendChild(li);315 }316 });317})();318</script>319{% endblock %}320```321
322live example: [docs.sublimated.com/zola/search/](https://docs.sublimated.com/zola/search/)323
324## what works325
326- markdown with TOML frontmatter327- tera templates with inheritance6 unmodified lines334- Atom/RSS feeds335- clean URLs336- dark mode (CSS `prefers-color-scheme`)337- co-located images and binary assets338- client-side search (elasticlunr.js)339
340## what doesn't work yet341
342- sass/scss compilation279- search index generation343- zola image processing (`resize_image()`)344- `load_data()` from external URLs345- multilingual sites (`default_language` config)346
3 unmodified lines