Skip to content

Search tags, filters, functions and guides.

JavaScript API / Loaders

JavaScript API

Loaders

Tell Kiln where templates come from.

A loader tells Kiln where to find templates. Kiln asks it for a template by name the first time the template is used.

memoryLoader

Holds templates in memory, as an object or a Map. It works everywhere, including Cloudflare Workers. A template can be its source or a precompiled module.

import { createKiln, memoryLoader } from "@lucidkiln/core";

const kiln = createKiln({
	loader: memoryLoader({
		"layouts/base.kiln": layoutSource,
		"pages/home.kiln": homeSource,
	}),
});

fileLoader

Reads templates from a folder. It is for Node only, so it lives in a separate entry point that never ends up in a Workers bundle.

  • It never reads files or folders whose names start with a dot, such as .env.
  • It does not follow symlinks below its root, whether they point to files or folders. They are missing templates and are not listed. The root itself may be a symlink.
  • A name that points to a folder, or to nothing, is a missing template.
  • Other read errors name the template and the error code, such as EACCES, but never the path on disk.
import { fileLoader } from "@lucidkiln/core/node";

const kiln = createKiln({
	loader: fileLoader({ root: "src/templates" }),
});

Your own loader

A loader is an object with a load method. It gets a resolved name, such as pages/home.kiln, and returns the source or a precompiled module, or null if the template doesn't exist. It can be async, returning a promise or any other thenable.

Kiln keeps each template it loads until you call invalidate. It remembers only a limited number of missing names, so names built from requests can't fill memory. A template that fails to load or compile is loaded again the next time it is used.

import type { Loader } from "@lucidkiln/core";

const kvLoader = (kv: KVNamespace): Loader => ({
	load: (name) => kv.get(`templates/${name}`),
});

Listing templates

A loader can also have a list method that returns the name of every template it holds, such as pages/home.kiln. Kiln never calls it while rendering. Tools use it, such as generateTypes.

  • memoryLoader lists every template you gave it.
  • fileLoader lists every file under its root, skipping symlinks and files and folders whose names start with a dot. It does not enter skipped folders.
  • In your own loader, list is optional and can be async.
const kvLoader = (kv: KVNamespace): Loader => ({
	load: (name) => kv.get(`templates/${name}`),
	list: async () =>
		(await kv.list({ prefix: "templates/" })).keys.map((key) =>
			key.name.slice("templates/".length),
		),
});

Names

Kiln resolves names before it calls the loader. The loader gets a clean path relative to its root, with the .kiln extension added when the name has none. Kiln rejects names that would point above the root. See Template names.