The configuration
The config file of a project is _smalldocs.yml, in the folder of the project. smalldocs can also read
_quarto.yml, the config file of Quarto. See A _quarto.yml below.
project:
type: website
website:
title: My project
theme: cosmo # the options of each page are at the top level
toc: true
linkify: true # the options of smalldocs are at the top level too; see Linkify below
api:
packages: [mypkg]An option is a key in _smalldocs.yml, in a _metadata.yml file or in the front matter of a page.
smalldocs merges the options in this order, and a later value wins:
- The top level of
_smalldocs.yml. - A
_metadata.ymlfile in each folder on the path to the page. smalldocs does not read a_metadata.ymlin the folder of the project. Put those options in_smalldocs.yml. - The front matter of the page.
metadata-files is a list of more YAML files, with paths from the folder of the project. smalldocs
merges them into _smalldocs.yml, and a key in _smalldocs.yml wins over the same key in these files.
If smalldocs does not read an option, the build gives a warning. See Options that smalldocs does not read.
Each table below gives the default of each option, which is what smalldocs does when you do not set it.
The smallest config is a _smalldocs.yml with no keys. Then smalldocs builds every page in the
folder with the theme cosmo, and with no navbar, sidebar or table of contents.
project
| Key | What it does | Default |
|---|---|---|
type |
website, or default, which is the same. book, a type of project in Quarto, is built as a website, with its chapters as the sidebar. Another type stops the build |
website |
output-dir |
The output folder. See the note below the table | _site |
render |
One glob, or a list of globs, of the pages to build. A glob is a path pattern; see Globs. A glob that starts with ! leaves pages out |
Every .qmd, .md and .ipynb file, except the files that are left out below |
resources |
One glob, or a list of globs, of more files to copy into the site, such as .nojekyll or images/** |
None. A file that a page links to, such as an image, is copied without this option |
pre-render, post-render |
Commands to run before and after the build, in the folder of the project. A command that is one .py file runs with the Python of smalldocs. See the note below the table |
None |
A command of pre-render or post-render gets these environment variables. Their names come from
Quarto, so a script written for Quarto still works:
QUARTO_PROJECT_DIR: the folder of the projectQUARTO_PROJECT_OUTPUT_DIR: the output folder, from the folder of the projectQUARTO_PROJECT_INPUT_FILESandQUARTO_PROJECT_OUTPUT_FILES: the pages and the files that the build writes, one on each line, as paths from the folder of the projectQUARTO_PROJECT_RENDER_ALL:1, because each build makes every pageSMALLDOCS:1, so a script can tell smalldocs from Quarto
Each build deletes the old content of the output folder. So smalldocs refuses an output folder in these cases:
- The folder is the project, or a folder above the project.
- The folder holds a
.gitfolder. - The folder holds files, but no
site_libsfolder. Asite_libsfolder shows that an earlier build made the folder.
Without render, smalldocs leaves out these files:
- the files and folders whose names start with
_or. - the output folder
- the folders
env,venv,renv,node_modules,site-packagesand__pycache__ - each file with the name
README, such asREADME.mdorreadme.qmd
To build a page that one of these rules leaves out, list it in render.
Globs
A glob is a path pattern, such as guide/*.qmd. smalldocs reads globs by these rules, which are the
rules of Quarto:
- In a glob with a
/, the*stays inside one folder, and**crosses folders. Soguide/*findsguide/a.qmd, but notguide/old/b.qmd.guide/**finds both. - A glob with no
/, such as*.qmd, finds files in every folder. - A folder name, such as
guide/, means the pages in the folder.
Sometimes a page links to a page that is not built, for example a draft. smalldocs reports the link, and it never copies the source of that page into the site.
website
| Key | What it does | Default |
|---|---|---|
title |
The name of the site, in the navbar and in the browser tab after the title of the page | None. The browser tab shows only the title of the page |
description |
The summary of the site. The home page uses it when its front matter has no description |
None |
site-url |
The address of the site. smalldocs needs it for sitemap.xml and for feeds |
None, and smalldocs writes no sitemap.xml |
repo-url, repo-subdir |
The repository of the site, and the folder of the site in it | None |
repo-branch |
The branch for the edit and source links |
main |
repo-actions |
Links under the table of contents: edit, source, issue. They need repo-url |
None |
navbar |
left, right, tools, title, logo, background, search. An entry is a page, or href and text, with an icon. url is another name for href. menu makes a dropdown. See Links in the navigation |
No navbar. The sidebar then shows the title of the site |
navbar.collapse-below |
The width of the window below which the navbar folds into a menu button: sm, md, lg, xl or xxl |
lg |
navbar.collapse |
false keeps the navbar open at every width, with no menu button |
true |
navbar.toggle-position |
The side of the menu button on a narrow screen: left or right |
After the title |
navbar.tools-collapse |
false keeps the tools out of the folded menu, so they show at every width |
The tools are in the folded menu |
navbar.pinned |
false hides the navbar while the reader scrolls down. The navbar comes back when the reader scrolls up |
The navbar stays on the screen |
navbar.logo, sidebar.logo |
A path to an image, or path and alt. Or light and dark, each a path or path and alt. With light and dark, the page shows the image of its mode. website.logo sets both |
None, or the logo of a theme extension |
navbar.logo-alt, sidebar.logo-alt |
The text of the logo for a screen reader | Empty |
navbar.logo-href, sidebar.logo-href |
The link of the logo. In the navbar, the title of the site has the same link | The home page |
sidebar |
contents, style, title, logo, search, tools, collapse-level. A list gives several sidebars |
No sidebar |
sidebar.background, sidebar.foreground |
The colour of the sidebar, and the colour of its links. Give the name of a colour of Bootstrap, such as light or primary, or a CSS colour, such as #f4f4f4 |
The colours of the theme |
sidebar.border |
true draws a line at the right of the sidebar. false removes the line |
A line for a docked sidebar only |
sidebar.alignment |
The alignment of the title, the logo and the tools, when there is no navbar: left, center or right |
left |
sidebar.header, sidebar.footer |
Markdown above and below the entries of the sidebar. The value can be the path of a Markdown file | None |
sidebar.pinned |
With no navbar, false hides the top bar of a narrow screen while the reader scrolls down |
The bar stays on the screen |
sidebar.style |
floating sits beside the text, and docked is a full-height panel at the left edge |
floating |
sidebar.collapse-level |
The sections above this level start open. With 2, the top-level sections start open, and the sections inside them start closed. A section that holds the current page is always open |
2 |
page-navigation |
Links to the previous page and the next page of the sidebar | Off |
page-footer |
One text, or left, center and right. Each part is Markdown or a list of entries |
None |
page-footer.background, page-footer.foreground |
The colour of the footer, and the colour of its text. The values are as for sidebar.background |
The colours of the theme |
page-footer.border |
false removes the line above the footer |
A line |
search |
The search box. false turns search off. See Search |
On |
favicon |
The icon in the browser tab | None |
open-graph |
The Open Graph tags, which give the title and the picture that a link to the page shows in other apps. true, or locale and site-name |
Off |
twitter-card |
The Twitter card tags, which do the same for Twitter. true, or card-style, creator, site, title, description and image |
Off |
google-analytics |
The tracking id of Google Analytics, such as G-ABC123. Or tracking-id, with anonymize-ip: true and storage: none |
None |
back-to-top-navigation |
A Back to top link at the bottom of the window. It shows when the reader scrolls up | Off |
other-links, code-links |
Lists of links under the table of contents. An entry has text, href, icon, rel and target. In code-links, the entry repo links to repo-url |
None |
draft-mode, drafts |
What a build does with a draft, and a list of pages that are drafts. See Drafts | gone, and no list |
comments |
A service for comments on each page: giscus, utterances or Hypothesis. See Comments | None |
bread-crumbs |
The breadcrumbs, the path of the page above its title. false hides them |
On |
The contents of a sidebar takes these entries:
sidebar:
contents:
- index.qmd # a page
- section: Guide # a section that folds
contents: guide/* # a glob: by `order:`, then the index page, then by path
- section: Reference
href: api/index.qmd # a section that is also a page
contents:
- api/one.qmd
- auto: examples # one section for each folder, titled by its index page
- text: Elsewhere
href: https://example.com
- text: "---" # a lineSearch
The search box is in the navbar. With no navbar, it is in the sidebar. These options change it:
website:
search:
location: sidebar # navbar or sidebar
type: overlay # textbox, or overlay: an icon that opens the box
limit: 10 # the number of results; 20 if you set none
keyboard-shortcut: [f, /, s] # the keys that go to the boxThe key / goes to the search box when you set no keyboard-shortcut. Quarto uses f, / and s;
write keyboard-shortcut: [f, /, s] to get the same keys. Ctrl-K and Cmd-K also go to the box. smalldocs does not read algolia and the other options of Quarto for search.
Drafts
A draft is a page that is not ready. A page with draft: true is a draft, and so is each page in
website.drafts. website.draft-mode sets what a build does with a draft:
gone, the default, leaves the draft out of the site.unlinkedbuilds the draft, but the sidebar, the navbar, the listings, the search, the sitemap and the feeds leave it out. A reader with the address can open it.visiblebuilds the draft as any other page.
website:
draft-mode: unlinked
drafts: [posts/next-post.qmd]The options of a page
Write these options at the top level of _smalldocs.yml or of a _metadata.yml file. A page can also
set them in its front matter. smalldocs reads theme only from the config of the
project. It reads order only from the front matter of a page.
| Key | What it does | Default |
|---|---|---|
theme |
A Bootswatch name, a CSS file, an extension in _extensions/, or light: and dark: for two themes and a toggle. See Themes |
cosmo |
css |
Your stylesheets, after the stylesheet of the theme | None |
toc |
The table of contents at the right of the page | Off |
toc-depth |
The deepest level of heading in the table of contents | 3 |
toc-location |
right, left, body, left-body or right-body. left puts the table in the sidebar, under the entries. body puts the table under the title. left-body and right-body show it in two places |
right |
toc-expand |
The number of levels of the table that show. A lower level opens when the reader comes to its section. true shows every level, and false shows only the top level |
Every level shows |
reference-location |
margin puts each footnote in the margin, beside the text that cites it. See Writing pages |
document: the end of the page |
fig-cap-location |
margin puts the caption of each figure in the margin. cap-location does the same |
bottom |
fig-align |
left, right or center: where each figure goes. See Figures |
center, which keeps the figure at the left of the column, with its picture in the centre of the figure |
tbl-cap-location |
top, bottom or margin: where the caption of each table goes |
top |
toc-title |
The heading above the table of contents | On this page |
number-sections |
Numbers before the headings | Off |
number-depth |
The deepest level of heading that gets a number. With 2, a ### heading has no number |
Every level |
anchor-sections |
The link that shows beside a heading when the pointer is on it. false removes it |
On |
code-copy |
The copy button on code | On |
code-line-numbers |
Numbers before the lines of each code block | Off |
code-overflow |
wrap wraps a long line of code onto the next line. scroll scrolls it to the side |
scroll |
code-fold |
true folds the code of each cell, and show folds it but starts open. See Writing pages. The code options of a page do not apply to the cells of a notebook |
false |
code-summary |
The words on the line of a folded cell | Code |
callout-appearance |
The style of each callout: default, simple or minimal |
default |
callout-icon |
false removes the icon of each callout |
true |
from |
Turns off a part of the Markdown. markdown-smart keeps quotes and dashes as you type them. markdown-tex_math_dollars reads each $ as a dollar. markdown-smart-tex_math_dollars does both |
markdown, with every part on |
page-layout |
article, full or custom |
article |
link-external-newwindow |
Open links to other sites in a new tab | Off |
link-external-icon |
An icon after each link to another site | Off |
link-external-filter |
A regular expression, which is a pattern of text, for the addresses that are not other sites, such as ^https://example\.com/ |
Only a link to the same host is not another site |
smooth-scroll |
A link to a heading of the page scrolls smoothly to it | Off |
mainfont, monofont, fontsize, linestretch, linkcolor, backgroundcolor, fontcolor, max-width |
The fonts, the colours and the width of the text. See Themes | The values of the theme |
pagetitle |
The title in the browser tab, in place of the title of the page | The title of the page |
title-prefix |
The text after the title in the browser tab, in place of the title of the site | The title of the site |
keywords |
A list of words for the keywords meta tag. The title block shows them too |
None |
license |
A Reuse section at the end of the page. A Creative Commons name, such as CC BY or CC BY-SA 4.0, links to its licence. Or give text, or text and url |
None |
copyright |
A Copyright section at the end of the page. Give text, or holder and year |
None |
include-in-header, include-before-body, include-after-body |
Files, or text: entries, to put into each page |
None |
echo, output, include, execute |
false hides the code or the output of every cell, in a notebook or in a page. execute: {echo: false} works too |
true: the code and the output show |
title |
The title of the page | A level-one heading (#) at the very top of the page. Otherwise the name of the file, with a space for each - and _ |
subtitle, description, author, date, categories, image |
The title block, which is the title, subtitle, author and date at the top of the page. Also what a listing shows | None |
date-format |
How the title block writes date, such as YYYY-MM-DD, long or short |
MMMM D, YYYY, such as October 12, 2026 |
draft |
true makes the page a draft. See Drafts |
false |
order |
The place of a page among the pages that a glob of the sidebar finds. A listing has its own sort |
None. The page comes after the pages that have an order |
listing |
A list of other pages. See Listings | None |
title-block-banner |
A band of the primary colour behind the title | Off |
Options that smalldocs does not read
smalldocs gives a warning for each key of the config that it does not read. It checks the keys inside each section too, down to each entry of the navbar and the sidebar. So a key with a typing error does not go unseen:
warning: unknown key website.sidebar.stylee
warning: unknown key website.navbar.left[0].colourIn a _quarto.yml, each option under format.html that smalldocs does not read gives a warning too.
Under execute, smalldocs reads echo, output and include. The other keys there are for running
code, so each gives the warning below.
Front matter and a _metadata.yml file can hold keys of your own, such as version: 2. A
shortcode such as meta can read them, so smalldocs gives no warning for
them. It gives a warning only for an option of Quarto that it does not read, such as lightbox:
warning: guide/intro.qmd: lightbox is not read by smalldocsSome options of Quarto tell it how to run the code of a page. They are jupyter, engine, knitr,
freeze, cache, execute-dir, df-print, keep-ipynb, ipynb-filters and
ipynb-shell-interactivity. smalldocs runs no code, so the warning for each of them says so:
warning: freeze is ignored: smalldocs runs no codeA warning does not stop the build. With smalldocs render --strict, the build ends with the exit code 1
when it gives a warning. Use --strict in the recipe that checks a project before a commit.
The options of smalldocs
These options belong to smalldocs. They are at the top level of _smalldocs.yml.
| Key | What it does | Default |
|---|---|---|
linkify |
A documented name in backticks links to its entry in the API reference. See Linkify | On when api has packages, or when the filters of a _quarto.yml name linkify.lua. Off otherwise |
symbols |
The index of names that linkify reads, from the folder of the site. Set it only for an index that you write yourself, without api. The api section always writes _symbols.json |
_symbols.json |
api |
The API reference. See The API reference | None: no reference |
Linkify
Linkify turns a name in backticks into a link to the entry of that name in the API reference. For
example, `Site.build` and `Site.build()` link to the entry of Site.build. Linkify links
only names that look like code, such as a call, a dotted name or a class. A plain lowercase word, such
as main, stays as code. See Links from the text.
Linkify reads the names and their links from the file _symbols.json, in the folder of the site. When
the config has api, each build writes this file before it builds the pages. See
The index of names.
smalldocs decides whether linkify is on in this order:
linkify, if you set it.linkify: trueturns it on, andlinkify: falseturns it off.api.linkify, if you set it.- Otherwise, linkify is on when
apihaspackages.
What a build writes
A build writes the pages, and these files, into the output folder:
index.html, the home page, fromindex.qmd,index.mdorindex.ipynbat the top of the folder. The title of the site in the navbar links to it. A folder can have an index page too. A link to the folder opens it, and anautosection of the sidebar takes its title.search.json, the index of the search box. It has one entry for each section of each page, with the title of the section and its text. A page withsearch: falsein its front matter is not in it.sitemap.xml, the list of pages for search engines, whensite-urlis set.site_libs, the stylesheets and the scripts of the site.- A feed for each listing that asks for one, when
site-urlis set. See Listings. - A copy of each file that a page links to, such as an image, and of the files of
resources,cssandfavicon. Each copy keeps its path from the folder of the project.
With an api section, a build first writes the reference pages and _symbols.json into the folder of
the project. Then it builds them as it builds the other pages. See The API reference.
A _quarto.yml
smalldocs looks for _smalldocs.yml first. If the folder has no _smalldocs.yml, smalldocs reads
_quarto.yml. If the folder has both files, smalldocs reads only _smalldocs.yml, and gives a warning.
A _quarto.yml has the same project and website sections. Two parts are in other places:
- The options of a page are under
format.html. - The options of smalldocs are under
smalldocs:. Quarto ignores a top-level key that it does not know, so Quarto can still build the project.
format:
html:
theme: cosmo
toc: true
smalldocs:
linkify: true
api:
packages: [mypkg]Under smalldocs:, theme names the theme that smalldocs uses, in place of format.html.theme. So
Quarto can compile its Sass theme, and smalldocs can use the CSS of the same extension.
smalldocs also reads a custom format of an extension, such as format: tufte-html, as html. See
Themes.
To move to _smalldocs.yml, rename the file. Move the keys of format.html and of smalldocs: to the
top level. Then remove format and filters. If you write format, smalldocs or filters in
_smalldocs.yml, the build gives a warning and does not read the key.
Lua filters
smalldocs runs no Lua. Its linkify is Python code, and it does the work of the Lua filter
linkify.lua, with one difference. The filter links every name in the index. smalldocs links only
names that look like code, so a plain lowercase word, such as encode, stays as code. Write it as a
call, encode(), to link it.
In a _quarto.yml, a file with the name linkify.lua in filters also turns on linkify, as step 3
of the list above. smalldocs does not read the file linkify.lua, and does not run it. The name only
tells smalldocs to turn on linkify. The entry can be a path, such as filters/linkify.lua, or
{path: linkify.lua}.
smalldocs does not run the other filters in filters. It gives a warning for each of them, but not for
the entry quarto, which only marks where the filters of Quarto run.
Comments
commentsadds a service for comments to each page. Set it inwebsiteor in the options of a page.comments: falsein the front matter of a page turns comments off on that page.repo,repo-id,category,category-id,mapping,reactions-enabled,loading,input-position,language, andtheme, which is a name orlightanddark. The giscus website gives the ids.repo,label,themeandissue-term.true, or the options of Hypothesis.