Color mode

Configuration reference

This page lists every field in riebeckite.config.ts. For how the configuration is resolved (filesystem roots, content selection, publishing rules), see Configuration.

Writing the config file

Create riebeckite.config.ts at the application root and export the result of defineConfig.

ts
import { defineConfig } from "@riebeckite/core";
 
export default defineConfig({
  site: {
    title: "My site",
    baseUrl: "https://example.com",
  },
});

defineConfig is a type-checking helper: it returns its argument unchanged and adds no runtime behavior. Keep export default as the config entry so the integration can import it.

Riebeckite resolves the config file from configRoot. For the Vite integration this defaults to the application root, and the file name defaults to riebeckite.config.ts. The CLI searches parent directories from the current directory and also accepts riebeckite.config.js and riebeckite.config.mjs. If the file lives elsewhere or has a different name, pass configRoot and configFile to riebeckiteVite().

Top-level sections

Section Required Purpose
site Yes Site identity and SEO defaults
content No Where content is read and what is published
theme No Appearance and design tokens
plugins No Content, rendering, and discovery features
cache No Persistent build cache

Only site is required. Every other section falls back to the default in its table.

site

site identifies the site and supplies fallbacks for page metadata.

Field Type Default Effect
title string required, non-empty Site name. Appears in page titles, og:site_name, and JSON-LD publisher.name.
description string "" Fallback for <meta name="description">, og:description, and JSON-LD.
author string "" <meta name="author"> and JSON-LD author.
baseUrl string "" Absolute HTTP(S) URL used to build canonical, Open Graph, feed, and webmention URLs.
locale string "en" <html lang> and og:locale. SEO converts _ to - in inLanguage.
twitterSite string "" Value for <meta name="twitter:site">. The site shell emits the tag; the SEO plugin does not.
defaultOgImage string "" Fallback image for og:image and twitter:image.
feed object see below Feed metadata.

title must be a non-empty string. baseUrl must be an absolute HTTP(S) URL when set. The remaining strings may be omitted or empty.

site.feed

feed.title and feed.description fall back to site.title and site.description; feed.language falls back to site.locale.

Field Type Default Effect
title string site.title RSS, Atom, and JSON feed title.
description string site.description Feed description.
language string site.locale Feed language tag.
ts
site: {
  title: "My site",
  description: "Notes and writing",
  baseUrl: "https://example.com",
  locale: "ja_JP",
  feed: { language: "ja" },
}

content

Field Type Default Effect
directory string "content" Filesystem directory containing the content.
source ContentSource undefined Custom reader. Replaces the filesystem reader.
exclude string[] [] Glob patterns removed before content is processed.
filters.publishStrategy "explicit" | "selective" "explicit" Default publishing policy. Frontmatter can override it per note.

content.directory

A relative directory resolves against the application root (appRoot), never against configRoot or process.cwd(). See Filesystem roots and external vaults.

content.source

Set source to replace the filesystem reader with another source, such as a remote store. Do not configure directory and source as two readers for the same content.

ts
type ContentSource = {
  scan(): Promise<readonly ContentSourceEntry[]>;
  read(entry: ContentSourceEntry): Promise<string | Uint8Array>;
};
 
type ContentSourceEntry = {
  path: string;
  metadata?: {
    modifiedAt?: number;
    size?: number;
    etag?: string;
    hash?: string;
  };
};

scan returns the logical paths to load. read returns one entry's content as a string or bytes. Metadata is optional and used by the cache.

content.exclude

Patterns match logical paths. * matches within one path segment, ** matches across segments, and ? matches one character.

ts
content: {
  directory: "content",
  exclude: ["drafts/**", "**/private/**", ".obsidian/**"],
}

Excluded files never enter the content pipeline, so they are unavailable for links, graph analysis, and diagnostics. This differs from draft and unlisted, which stay in the content system but are hidden from routes or discovery. See Publishing state.

content.filters.publishStrategy

Value A note is public when
"explicit" Frontmatter has publish: true.
"selective" Frontmatter does not have private: true or draft: true.

Frontmatter visibility and publishAt take precedence over the strategy. The full decision table is in Publishing state.

theme

theme accepts either a raw ThemeConfig object or a theme returned by defineTheme. With a raw object or no theme at all, the default theme stylesheet is used. A declared theme supplies its own stylesheets.

Raw ThemeConfig

Field Type Default Effect
name string "riebeckite" Theme identity. Sets data-theme-name.
colorMode "light" | "dark" | "system" "system" Initial color mode. "system" omits data-theme and follows the OS.
typography "system" | "serif" | "sans" "system" Sets data-typography for font presets.
articleLayout "article" | "sidebar" | "full-width" "article" Sets data-article-layout.
tokens ThemeDesignTokens {} Semantic values emitted as --rb-* CSS custom properties.
attributes Record<`data-${string}`, string | undefined> {} Extra data-* attributes. Only data-* keys are kept, and framework-owned names (data-theme, data-theme-name, data-typography, data-article-layout) are dropped.
userCss string[] [] Stylesheet hrefs emitted as <link rel="stylesheet"> after theme styles. Use public paths such as /app/custom.css.

theme.tokens

Group Fields
color paper, ink, muted, accent, border, borderStrong, surface, surfaceHover, overlay, danger, success, codeBackground
typography bodyFont, headingFont, monoFont
layout pageMaxWidth, articleMaxWidth, sidebarWidth, contentGap

Each token maps to a --rb-* custom property. See Design tokens for the full mapping.

theme.tokens is emitted as an unlayered :root { --rb-* } rule after the theme stylesheet, so a value set here overrides the theme's value in every mode (light, explicit dark, and system dark). Adjust accents and surfaces here instead of copying theme CSS.

ts
theme: {
  colorMode: "system",
  typography: "serif",
  articleLayout: "sidebar",
  tokens: { color: { accent: "#c2410c" } },
  userCss: ["/app/custom.css"],
}

Declared themes

A theme package exposes a factory. Pass its options and hand the result to theme.

ts
import { rerurateTheme } from "@riebeckite/theme-rerurate";
 
export default defineConfig({
  site: { title: "My site" },
  theme: rerurateTheme({ colorMode: "system", motion: true }),
});

Theme-specific options are owned by the theme package, not by Core. See Theme system.

plugins

plugins is an array of plugin instances. false, null, and undefined are dropped, so a boolean can toggle a plugin.

ts
plugins: [
  obsidianMarkdown(),
  enableSearch && searchPlugin(),
]

Resolution removes disabled inputs, orders enabled plugins by order, and validates capabilities. Two enabled plugins that share a name fail resolution. Each plugin's validateOptions runs while the config is resolved.

Individual plugin options are documented in the plugin guides and the Plugin system.

cache

cache controls the persistent build cache.

Field Type Default Effect
enabled boolean true Set false to disable the cache and rebuild everything.
directory string <buildDirectory>/cache Overrides where cache entries are stored.

Disabling the cache or moving its directory affects build time only, not the output. See Build cache.

Validation

An invalid configuration throws ConfigValidationError, which lists each offending path and message. Do not catch and ignore it. Run check after any change:

sh
npm exec riebeckite check

See also

History

1 changesCollapseExpand
1 + # Configuration reference
2 +
3 + This page lists every field in `riebeckite.config.ts`. For how the configuration
4 + is resolved (filesystem roots, content selection, publishing rules), see
5 + [Configuration](./configuration.en.md).
6 +
7 + ## Writing the config file
8 +
9 + Create `riebeckite.config.ts` at the application root and export the result of
10 + `defineConfig`.
11 +
12 + ```ts
13 + import { defineConfig } from "@riebeckite/core";
14 +
15 + export default defineConfig({
16 + site: {
17 + title: "My site",
18 + baseUrl: "https://example.com",
19 + },
20 + });
21 + ```
22 +
23 + `defineConfig` is a type-checking helper: it returns its argument unchanged and
24 + adds no runtime behavior. Keep `export default` as the config entry so the
25 + integration can import it.
26 +
27 + Riebeckite resolves the config file from `configRoot`. For the Vite integration
28 + this defaults to the application root, and the file name defaults to
29 + `riebeckite.config.ts`. The CLI searches parent directories from the current
30 + directory and also accepts `riebeckite.config.js` and `riebeckite.config.mjs`.
31 + If the file lives elsewhere or has a different name, pass `configRoot` and
32 + `configFile` to `riebeckiteVite()`.
33 +
34 + ### Top-level sections
35 +
36 + | Section | Required | Purpose |
37 + | --- | --- | --- |
38 + | `site` | Yes | Site identity and SEO defaults |
39 + | `content` | No | Where content is read and what is published |
40 + | `theme` | No | Appearance and design tokens |
41 + | `plugins` | No | Content, rendering, and discovery features |
42 + | `cache` | No | Persistent build cache |
43 +
44 + Only `site` is required. Every other section falls back to the default in its
45 + table.
46 +
47 + ## site
48 +
49 + `site` identifies the site and supplies fallbacks for page metadata.
50 +
51 + | Field | Type | Default | Effect |
52 + | --- | --- | --- | --- |
53 + | `title` | `string` | required, non-empty | Site name. Appears in page titles, `og:site_name`, and JSON-LD `publisher.name`. |
54 + | `description` | `string` | `""` | Fallback for `<meta name="description">`, `og:description`, and JSON-LD. |
55 + | `author` | `string` | `""` | `<meta name="author">` and JSON-LD `author`. |
56 + | `baseUrl` | `string` | `""` | Absolute HTTP(S) URL used to build canonical, Open Graph, feed, and webmention URLs. |
57 + | `locale` | `string` | `"en"` | `<html lang>` and `og:locale`. SEO converts `_` to `-` in `inLanguage`. |
58 + | `twitterSite` | `string` | `""` | Value for `<meta name="twitter:site">`. The site shell emits the tag; the SEO plugin does not. |
59 + | `defaultOgImage` | `string` | `""` | Fallback image for `og:image` and `twitter:image`. |
60 + | `feed` | `object` | see below | Feed metadata. |
61 +
62 + `title` must be a non-empty string. `baseUrl` must be an absolute HTTP(S) URL
63 + when set. The remaining strings may be omitted or empty.
64 +
65 + ### site.feed
66 +
67 + `feed.title` and `feed.description` fall back to `site.title` and
68 + `site.description`; `feed.language` falls back to `site.locale`.
69 +
70 + | Field | Type | Default | Effect |
71 + | --- | --- | --- | --- |
72 + | `title` | `string` | `site.title` | RSS, Atom, and JSON feed title. |
73 + | `description` | `string` | `site.description` | Feed description. |
74 + | `language` | `string` | `site.locale` | Feed language tag. |
75 +
76 + ```ts
77 + site: {
78 + title: "My site",
79 + description: "Notes and writing",
80 + baseUrl: "https://example.com",
81 + locale: "ja_JP",
82 + feed: { language: "ja" },
83 + }
84 + ```
85 +
86 + ## content
87 +
88 + | Field | Type | Default | Effect |
89 + | --- | --- | --- | --- |
90 + | `directory` | `string` | `"content"` | Filesystem directory containing the content. |
91 + | `source` | `ContentSource` | `undefined` | Custom reader. Replaces the filesystem reader. |
92 + | `exclude` | `string[]` | `[]` | Glob patterns removed before content is processed. |
93 + | `filters.publishStrategy` | `"explicit"` \| `"selective"` | `"explicit"` | Default publishing policy. Frontmatter can override it per note. |
94 +
95 + ### content.directory
96 +
97 + A relative `directory` resolves against the application root (`appRoot`), never
98 + against `configRoot` or `process.cwd()`. See
99 + [Filesystem roots and external vaults](./configuration.en.md#filesystem-roots-and-external-vaults).
100 +
101 + ### content.source
102 +
103 + Set `source` to replace the filesystem reader with another source, such as a
104 + remote store. Do not configure `directory` and `source` as two readers for the
105 + same content.
106 +
107 + ```ts
108 + type ContentSource = {
109 + scan(): Promise<readonly ContentSourceEntry[]>;
110 + read(entry: ContentSourceEntry): Promise<string | Uint8Array>;
111 + };
112 +
113 + type ContentSourceEntry = {
114 + path: string;
115 + metadata?: {
116 + modifiedAt?: number;
117 + size?: number;
118 + etag?: string;
119 + hash?: string;
120 + };
121 + };
122 + ```
123 +
124 + `scan` returns the logical paths to load. `read` returns one entry's content as
125 + a string or bytes. Metadata is optional and used by the cache.
126 +
127 + ### content.exclude
128 +
129 + Patterns match logical paths. `*` matches within one path segment, `**` matches
130 + across segments, and `?` matches one character.
131 +
132 + ```ts
133 + content: {
134 + directory: "content",
135 + exclude: ["drafts/**", "**/private/**", ".obsidian/**"],
136 + }
137 + ```
138 +
139 + Excluded files never enter the content pipeline, so they are unavailable for
140 + links, graph analysis, and diagnostics. This differs from `draft` and
141 + `unlisted`, which stay in the content system but are hidden from routes or
142 + discovery. See [Publishing state](./configuration.en.md#publishing-state).
143 +
144 + ### content.filters.publishStrategy
145 +
146 + | Value | A note is public when |
147 + | --- | --- |
148 + | `"explicit"` | Frontmatter has `publish: true`. |
149 + | `"selective"` | Frontmatter does not have `private: true` or `draft: true`. |
150 +
151 + Frontmatter `visibility` and `publishAt` take precedence over the strategy. The
152 + full decision table is in
153 + [Publishing state](./configuration.en.md#publishing-state).
154 +
155 + ## theme
156 +
157 + `theme` accepts either a raw `ThemeConfig` object or a theme returned by
158 + `defineTheme`. With a raw object or no `theme` at all, the default theme
159 + stylesheet is used. A declared theme supplies its own stylesheets.
160 +
161 + ### Raw ThemeConfig
162 +
163 + | Field | Type | Default | Effect |
164 + | --- | --- | --- | --- |
165 + | `name` | `string` | `"riebeckite"` | Theme identity. Sets `data-theme-name`. |
166 + | `colorMode` | `"light"` \| `"dark"` \| `"system"` | `"system"` | Initial color mode. `"system"` omits `data-theme` and follows the OS. |
167 + | `typography` | `"system"` \| `"serif"` \| `"sans"` | `"system"` | Sets `data-typography` for font presets. |
168 + | `articleLayout` | `"article"` \| `"sidebar"` \| `"full-width"` | `"article"` | Sets `data-article-layout`. |
169 + | `tokens` | `ThemeDesignTokens` | `{}` | Semantic values emitted as `--rb-*` CSS custom properties. |
170 + | `attributes` | ``Record<`data-${string}`, string \| undefined>`` | `{}` | Extra `data-*` attributes. Only `data-*` keys are kept, and framework-owned names (`data-theme`, `data-theme-name`, `data-typography`, `data-article-layout`) are dropped. |
171 + | `userCss` | `string[]` | `[]` | Stylesheet hrefs emitted as `<link rel="stylesheet">` after theme styles. Use public paths such as `/app/custom.css`. |
172 +
173 + ### theme.tokens
174 +
175 + | Group | Fields |
176 + | --- | --- |
177 + | `color` | `paper`, `ink`, `muted`, `accent`, `border`, `borderStrong`, `surface`, `surfaceHover`, `overlay`, `danger`, `success`, `codeBackground` |
178 + | `typography` | `bodyFont`, `headingFont`, `monoFont` |
179 + | `layout` | `pageMaxWidth`, `articleMaxWidth`, `sidebarWidth`, `contentGap` |
180 +
181 + Each token maps to a `--rb-*` custom property. See
182 + [Design tokens](./theme-api.en.md#design-tokens) for the full mapping.
183 +
184 + `theme.tokens` is emitted as an unlayered `:root { --rb-* }` rule after the
185 + theme stylesheet, so a value set here overrides the theme's value in every mode
186 + (light, explicit dark, and system dark). Adjust accents and surfaces here
187 + instead of copying theme CSS.
188 +
189 + ```ts
190 + theme: {
191 + colorMode: "system",
192 + typography: "serif",
193 + articleLayout: "sidebar",
194 + tokens: { color: { accent: "#c2410c" } },
195 + userCss: ["/app/custom.css"],
196 + }
197 + ```
198 +
199 + ### Declared themes
200 +
201 + A theme package exposes a factory. Pass its options and hand the result to
202 + `theme`.
203 +
204 + ```ts
205 + import { rerurateTheme } from "@riebeckite/theme-rerurate";
206 +
207 + export default defineConfig({
208 + site: { title: "My site" },
209 + theme: rerurateTheme({ colorMode: "system", motion: true }),
210 + });
211 + ```
212 +
213 + Theme-specific options are owned by the theme package, not by Core. See
214 + [Theme system](./theme-api.en.md).
215 +
216 + ## plugins
217 +
218 + `plugins` is an array of plugin instances. `false`, `null`, and `undefined` are
219 + dropped, so a boolean can toggle a plugin.
220 +
221 + ```ts
222 + plugins: [
223 + obsidianMarkdown(),
224 + enableSearch && searchPlugin(),
225 + ]
226 + ```
227 +
228 + Resolution removes disabled inputs, orders enabled plugins by `order`, and
229 + validates capabilities. Two enabled plugins that share a `name` fail
230 + resolution. Each plugin's `validateOptions` runs while the config is resolved.
231 +
232 + Individual plugin options are documented in the [plugin guides](../plugins/README.en.md)
233 + and the [Plugin system](./plugin-api.en.md).
234 +
235 + ## cache
236 +
237 + `cache` controls the persistent build cache.
238 +
239 + | Field | Type | Default | Effect |
240 + | --- | --- | --- | --- |
241 + | `enabled` | `boolean` | `true` | Set `false` to disable the cache and rebuild everything. |
242 + | `directory` | `string` | `<buildDirectory>/cache` | Overrides where cache entries are stored. |
243 +
244 + Disabling the cache or moving its directory affects build time only, not the
245 + output. See [Build cache](./configuration.en.md#build-cache).
246 +
247 + ## Validation
248 +
249 + An invalid configuration throws `ConfigValidationError`, which lists each
250 + offending path and message. Do not catch and ignore it. Run `check` after any
251 + change:
252 +
253 + ```sh
254 + npm exec riebeckite check
255 + ```
256 +
257 + ## See also
258 +
259 + - [Configuration](./configuration.en.md) — roots, content selection, publishing
260 + - [Plugin system](./plugin-api.en.md) — the plugin contract
261 + - [Theme system](./theme-api.en.md) — design tokens and the CSS contract
262 + - [CLI](./cli.en.md) — `check`, `doctor`, and `inspect`
263 +