psyche is a drop-in solution for searching documentation, inspired by Algolia's DocSearch.
Check out the notion-enhancer documentation for a live demo.
Warning: psyche is built specifically for searching documentation. It is not built for implementation into other interfaces (e.g. eCommerce) or use with custom data schemes.
The psyche client requires a pre-generated index of results to search.
This should be an array of Result
records (see types.d.ts).
Indexes are provided to the client programmatically, but should take the
form of an unformatted/minified .json
file.
Indexers are plugins/middleware that crawl a site and generate an index, either during a build process or on-the-fly if the site is dynamically served.
Indexers for some documentation generators are provided below. If your generator of choice is not yet supported, either open a feature request or write your own and open a pull request.
Add the following to your _config.ts
file:
import psyche from 'https://deno.land/x/psyche/indexers/lume.ts';
site.use(psyche());
The indexer can be configured by providing a LumeConfig
object
as the first argument of the psyche()
call (see types.d.ts).
By default:
/search.json
.data.section
or where data.draft = true
will be ignored.data.section_order
& sorted by data.order
.data.title
.data.section
.<article></article>
element
in a page are indexed according to semantic HTML. Other elements (e.g.
<blockquote></blockquote>
) are treated as paragraphs. This works best
with markdown output.Read the page data and/or shared data pages of Lume's documentation to see how to set these properties.
The psyche client is written in TypeScript. You can either directly import it if your site's assets will be bundled by e.g. ESBuild, or import the pre-transpiled and minified JavaScript build.
import psyche from 'https://deno.land/x/psyche/client/mod.ts';
// or
import psyche from 'https://deno.land/x/psyche/client/psyche.min.mjs';
The psyche
default export is a function that when provided with
a ClientConfig
object (see types.d.ts) will
return a ClientInstance
(see types.d.ts).
Calling .register()
on a client instance will insert the component
into the document and listen for hotkey presses. The component can
then be opened either by calling .open()
or by pressing CTRL/ā + K
.
E.g.
const searchInstance = psyche({
theme: { scrollbarStyle: 'square' },
index: await fetch('/search.json').then((res) => res.json()),
});
searchInstance.register();
searchInstance.open();
To add a hotkey to the list in the search modal,
add it to the hotkeys
array of psyche's ClientConfig
object (see types.d.ts).
For platform-dependent hotkeys, the named export platformModifier
will be equivalent to the ā key on MacOS or the CTRL
key on other platforms.
To handle hotkeys, provide a ClientHotkey
object (see types.d.ts)
to the named export registerHotkey
. This is a KeyboardEvent
partial with a few
additional properties:
platformModifier
property is equivalent to metaKey
on MacOS
or ctrlKey
on other platforms.onkeydown
property will be called when the key combination is pressed
down, passed the triggered KeyboardEvent
as its first argument.onkeyup
property will be called when the key combination is released,
passed the triggered KeyboardEvent
as its first argument.E.g.
import psyche, {
registerHotkey,
platformModifier,
} from 'https://deno.land/x/psyche/client/psyche.min.mjs';
registerHotkey({
key: 'l',
platformModifier: true,
shiftKey: true,
onkeydown: (event) => {
event.preventDefault();
toggleTheme();
},
});
const searchInstance = psyche({
hotkeys: [{ kbd: `${platformModifier} + SHIFT + L`, label: 'to toggle theme' }],
});
searchInstance.register();
Changes to this project are recorded in the CHANGELOG.
This project is licensed under the MIT License.
To support future development of this project, please consider sponsoring the author.