Plugins
Plugins extend the Kilim build. They run only at build time: nothing in a plugin reaches the browser except the output it changes, and pages stay free of JavaScript unless a plugin explicitly declares client scripts (see Client scripts).
Plugins are factories that return a plugin object. Add them to plugins in kilim.config.ts:
import { defineConfig } from "@kilim-dev/core";
import { readingTime } from "./plugins/reading-time.ts";
export default defineConfig({
plugins: [readingTime({ wordsPerMinute: 230 })],
audit: {
// Plugin rules are typed: `max` must be a number here.
rules: { "reading-time/too-long": ["error", { max: 15 }] },
},
});Plugins run in this order:
- the built-in ones the config leaves on:
feed,sitemap,og-image; - the theme's (
defineTheme({ plugins })), base theme first when itextendsanother; - the config's
plugins, in order.
A plugin with the same name as an earlier one replaces it, at its own position. That is how a site configures a theme's plugin, or a built-in one:
import { feed, sitemap } from "@kilim-dev/core/plugins";
export default defineConfig({
plugins: [feed({ formats: ["rss", "atom"], limit: 50 })],
});The config options feed, sitemap and ogImage are shorthands for the built-in plugins and stay supported: sitemap: false turns the sitemap plugin off, feed: { limit: 50 } is the same as plugins: [feed({ limit: 50 })]. Use one or the other for a plugin, not both.
@kilim-dev/core/plugins has these plugins:
| Plugin | On by default | What it writes |
|---|---|---|
sitemap() | yes | /sitemap.xml of the indexable pages, with language alternates. |
feed() | yes | RSS (and optionally Atom and JSON Feed) next to each collection list. |
ogImage() | yes | An Open Graph image per page from the theme's template. |
search() | no | A search index and the script of the theme's search box. |
llmsTxt() | no | /llms.txt and /llms-full.txt for language models. |
import { search } from "@kilim-dev/core/plugins";
export default defineConfig({
plugins: [search({ collections: ["docs"] })],
});search() writes /_kilim/search.json with each page's title, description, headings and the start of its text, and adds a small script to the pages that have a search box (an element with data-kilim-search; the default theme puts one above the docs sidebar, or in the header with the setting search: header). Other pages stay free of JavaScript. Matching runs in the browser, ignores accents and ranks titles over headings over text; a result can jump to the matching section.
| Option | Meaning |
|---|---|
collections | Collections to index; every published page by default. |
bodyLength | Characters of body text kept per page (default 2000); 0 keeps only headings. |
script | "inline" (default, allowed by a CSP hash) or "file", one cached script file. |
kilim check warns when the index grows past 500 KB (search/index-size).
import { llmsTxt } from "@kilim-dev/core/plugins";
export default defineConfig({
plugins: [llmsTxt({ collections: ["docs"] })],
});llmsTxt() writes /llms.txt (the site title, description and a linked list of pages per collection, as llmstxt.org describes) and /llms-full.txt, the Markdown source of those pages, for language models. full: false leaves out llms-full.txt. This site has both: /llms.txt. kilim check warns when an llms-full.txt grows past 500 KB, so that it still fits in the context of a language model (llms-txt/full-size).
Writing plugins covers definePlugin, the build hooks, frontmatter fields, audit rules and client scripts.