Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
It's finally here! ✨ Local, accessible, multi-lingual search ✨ using Elasticlunr.
Some of my favourite features:
Text fragments: Selecting a search result scrolls to and highlights the search term on the destination page (see browser support). See the video below for a demo.
Stylised modal: The search modal has a blurred background and uses the
--primary-color
CSS variable to apply a gentle tint, making it compatible with skins.Full keyboard navigation: Shortcuts for opening/closing the modal (
Ctrl/Cmd + K
), navigating results (arrow keys, Home/End, Page Up/Down, Enter) and Esc to close the modal. Tab is "trapped" between the search input and the clear button.Multilingual: The modal text, titles, ARIA labels and the search itself support multiple languages.
Efficient index loading: The search index loads on mouseover of the search icon or upon modal activation, whichever happens first. If a user doesn't interact with a search element, the index isn't loaded.
Accessibility focus: The implementation leverages ARIA attributes and roles, prioritising accessibility to cater to a wider range of users.
Responsive design, of course. And it works with taps just as well as with keyboard or mouse.
Flexible search indexing: Search works as long as there's something indexed: works with just titles/paths/description/content and any combination of these.
Compatibility with multiple Zola versions: Supports Zola version 0.17.2 (current version in Debian stable) with workarounds for existing bugs.
Advanced snippet generation: Includes a custom snippet generation algorithm to provide top-tier context.
Related issue
Resolves #190 (at last).
Changes
static/js/searchElasticlunr.js
contains the main logic (the minified version is the one that loads, though)static/js/lunr
.header.html
(loads JS) andfooter.html
(search modal loading, which is intemplates/partials/search_modal.html
projects/tabi
, Mastering tabi post and JavaScript post.Technical details — search flow
Logic below is written in
static/js/searchElasticlunr.js
.1. Initiating the Search Process
loadSearchIndex
.toggleModalVisibility
.openSearchModal
is called.window
object. If not, fetches it from a JSON file.2. User Enters Search Query
searchIndexPromise
to ensure the index is loaded.3. Processing the Search Results
div
for each.generateSnippet
to create relevant snippets with highlighted search terms.results
container.4. Displaying the Results
results
container.updateResultText
updates the result count.5. User Interaction with Results
keydown
event listener enables keyboard navigation within results.6. Closing the Search Modal
closeModal
hides the modal and clears search, managing focus return for accessibility.7. Additional Utility Functions
getByteByBinary
andsubstringByByte
handle string processing for non-ASCII characters.Accessibility
Several steps have been taken to ensure accessibility:
Semantic HTML: The search modal uses semantic HTML elements, which aids in conveying the structure and purpose to assistive technologies.
ARIA attributes: Extensive use of ARIA attributes, such as
aria-labelledby
,aria-hidden
,aria-expanded
,aria-controls
, andaria-activedescendant
, provide additional context, making the modal more accessible.Keyboard navigation: Implemented keyboard navigation within the search modal, allowing users to navigate and interact using the keyboard alone.
Screen reader compatibility: The
role
attributes and ARIA labels enhance compatibility with screen readers, offering a better experience for visually impaired users.Colour contrast: Uses the same CSS variables as the rest of tabi, ensuring proper contrast.
Focus keeping: When the search modal opens, focus shifts to the input field, and on closing, it returns to the last focused element before the modal was opened. This prevents keyboard and screen reader users from losing their place in the page.
I have tested this using macOS VoiceOver. @Almost-Senseless-Coder has stress-tested the accessibility features.
Video
Using keyboard navigation.
Type of change
Checklist
theme.toml
with a sane default for the featureconfig.toml
commentstheme.toml
commentsAcknowledgements