Configuration
Colophon is configured with a module whose default export is a
ColophonConfig. The CLI loads it with --config:
colophon content --config colophon.config.tsEvery field is optional, and sensible defaults apply. A project that only wants
its own brand colours can stop after colors.
import { defineConfig } from "@kensio/colophon";
export default defineConfig({ colors: { brand: "#2563eb", brandDark: "#1e3a8a", brandWarm: "#f59e0b" }, footer: "example.com", badge: { text: "npm" },});defineConfig is an identity function. It exists for the type checking and
editor completion, so you can drop it if you would rather annotate the export
yourself.
Options
Section titled “Options”| Option | Default | Notes |
|---|---|---|
colors |
neutral indigo/pink | brand, brandDark, brandWarm, foreground. |
background |
gradient derived from colors |
Or a { type: "solid" } or custom gradient. |
fonts |
none | Font files to render with. See Fonts. |
systemFonts |
true until fonts is set |
Whether installed fonts are loaded too. |
fontFamily |
first font, else Arial, ... |
Font stack for template text. |
footer |
none | Footer text. Omit the field for none. |
badge |
none | Corner badge for banner. Omit the field for none. |
code |
github-dark, monospace stack |
Styling for the code template. |
onWarning |
console.warn |
Where compromises are reported. See Warnings. |
sizes |
og and square |
Named output sizes. See Output sizes. |
templates |
banner, card, code |
Merged over the built-ins. See Templates. |
content |
meta_img_props, .md and .markdown files |
How props are read. See Frontmatter. |
placement |
beside-content |
Where images go and their URL. See Placement. |
manifest |
none | Path to write a JSON manifest to. See Manifest. |
extra |
none | Images not tied to a post. See One-off images. |
Computing config at build time
Section titled “Computing config at build time”The default export can also be a function returning the config, async or not.
Some configs cannot be written as a literal. Brand colours might be read out of
the site’s own stylesheet, a version pulled from package.json, or a footer
that names the current build. Without this, such a project has to give up the
CLI and drive generate from a script of its own.
import { readFile } from "node:fs/promises";
import { defineConfig } from "@kensio/colophon";
export default defineConfig(async () => { const theme = JSON.parse(await readFile("src/theme.json", "utf8"));
return { colors: { brand: theme.primary, brandDark: theme.primaryDark }, footer: "example.com", };});The function takes no arguments. Everything it might be handed is either already on the command line or a decision the config itself is making.
It is called once per run, before anything is walked or rendered, and what it returns is the config, validated and stamped exactly as a literal one would be. A config whose output changes therefore re-renders like any other edit, and one that merely reads a file that has not changed does not.
A module that exports neither an object nor a function is an error rather than a run with the defaults. The command line asked for that file, so quietly rendering the whole tree without it would be the worst of both. The same check catches a factory whose arrow body forgot to return.
Unknown options
Section titled “Unknown options”The config is closed. An option Colophon does not recognise stops the build rather than being ignored, because a key nobody reads is otherwise a build that succeeds and images that are wrong, with nothing in the log to say why.
Unknown option "dimensions". Did you mean "sizes"?Where there is an obvious near miss it is named, including options that have been renamed between versions. Where there is not, the message lists what is valid at that point in the config.
Nested objects are checked too, and named by their path: code.tabsize,
sizes[1].heigth, background.stops[0].ofset. Everything wrong with a config
is reported in one go rather than one run at a time.
Two parts stay open on purpose. The names under templates are your own, and a
post’s props are read by whichever template understands them.
Validation checks keys rather than the shape of what they hold, so
colors: "blue" still gets through to the type checker rather than being caught
here.
