Skip to content
DocPensieve
0.1.5

Configuration

The docpensieve.config.mjs file, at the root of the project.

It is an ES module — hence .mjs, which Node reads as one whatever the project's package.json says. docpensieve.config.js works too, in a project whose package.json declares "type": "module"; with both files present, the build stops rather than pick one.

/** @type {import('@docpensieve/core').DocPensieveConfig} */
export default {
  projectName: 'My documentation',
  siteUrl: 'https://example.com/my-project',

  versions: [{ slug: 'v1.0', name: '1.0', folder: 'docs/v1.0', current: true }],

  outDir: 'dist',

  theme: {
    framework: 'tailwind',
    darkMode: 'class',
  },

  sidebar: 'auto',
  globalComponents: true,
  jsonld: { enabled: true },
};

The @type comment gives autocompletion and type checking in the editor without importing anything: the file stays readable even where DocPensieve only runs through npx. In a project that installs it as a dependency, defineConfig from @docpensieve/core does the same.

docpensieve init writes this file with every field in it — set to its default, or commented out with an example — so that it also tells you what you can change.

The fields

FieldDefaultEffect
projectName'Documentation'Name shown in the header and in the JSON-LD
siteUrl''Public URL. Used for the canonical and the JSON-LD
baseUrl'/'Deployment prefix. Derived from siteUrl when omitted
outDir'dist'Output folder, relative to the root
versions[]At least one entry
themesee belowStyling
sidebar'auto''auto': the sidebar follows the file tree. The only value written so far
globalComponentstrueShipped components available without an import
scrollToToptrueBack-to-top button on every page
jsonld{ enabled: true }Structured data
lang'en'Language of the document, in <html lang>. The shell's labels stay English
logo''Image beside the project name, in the header
favicon''Icon of the browser tab: .ico, .png or .svg
socialImage''Preview of a shared page. Needs siteUrl

Images

logo: 'branding/logo.png',
favicon: 'branding/favicon.png',
socialImage: 'branding/social.png',

The paths start from the project root. Each image is copied into every version, under assets/, so that a version stays whole on its own branch.

  • logo sits beside the project name, at the height of the header's text: a square image reads best there. Its alt stays empty, since the name follows it. It is also the logo of the organisation in the structured data.
  • favicon is the icon of the browser tab: .ico, .png or .svg.
  • socialImage is what a social network shows of a shared page, with its title and description. 1200 × 630 pixels is the usual size, and SVG is not read there. Those networks only read an absolute address, hence siteUrl.

A declared image that does not exist stops the build, naming the field.

versions

versions: [
  { slug: 'v2.0', name: '2.0', folder: 'docs/v2.0', current: true },
  { slug: 'v1.0', name: '1.0', folder: 'docs/v1.0', archived: true },
],
FieldRole
slugURL and branch identifier
nameLabel shown in the switcher
folderSource folder, relative to the root
currentVersion served by default. At most one
archivedVersion kept but no longer maintained. Banner, but stays indexed
prereleaseVersion in preparation. Banner and noindex

theme

theme: {
  framework: 'tailwind',
  darkMode: 'class',
  tokens: { '--dp-accent': 'oklch(55% 0.2 250)' },
  css: '.dp-article h2 { letter-spacing: -0.01em; }',
  source: '@import "tailwindcss";',
},
FieldEffect
framework'tailwind' or 'custom'
darkModeDark theme strategy
tokensRedefined --dp-* tokens
cssCSS appended to the produced stylesheet
sourceStylesheet handed to the utility compiler

The available tokens are listed in Themes.

Longer rules go in the theme/ folder, at the root of the project: every .css file in it is appended after css, in name order, and docpensieve dev picks up every change. Under the custom theme, init starts it with theme/custom.css.

baseUrl, and why you rarely write it

A siteUrl with a sub-path already gives it: https://example.com/my-project produces baseUrl: '/my-project/'. Writing it is only useful to depart from it.

The prefix is normalised with both its slashes. It is what prefixes every internal link: if it is wrong, every link is.

What is refused

CaseMessage
The configuration is not an objectAn example of the expected export
No version declaredAn example of a complete entry
Two versions with the same slugThe offending slug
Several current versionsThe list of those found
Unknown frameworkThe accepted values
Requested slug not foundThe available slugs
An image of the wrong kindThe accepted extensions
socialImage without siteUrlWhy the address is needed
A declared image that is missingThe field and its path

Each one stops the build with a message and a hint, without a stack trace.

What is filled in automatically

If no version carries current, the first in the list becomes current. A single-version configuration therefore has nothing to specify — this field only starts to matter from the second version on.