Book (Documentation Site)¶
The Rhiza documentation site — referred to as the book — is built with MkDocs using the Material theme. This page explains how to customise its look and feel.
Building and Serving¶
# Build the full book (runs tests, exports notebooks, then builds MkDocs)
make book
# Serve the docs locally with live reload (useful while editing)
make serve
# Build only the MkDocs site (skips test reports and notebooks)
make book
The built site is written to _book/ by default. To change the output directory:
Configuration¶
The MkDocs configuration lives in mkdocs.yml at the root of the repository. Key settings:
| Setting | Description |
|---|---|
site_name |
The title shown in the browser tab and header |
site_url |
Canonical URL for the deployed site |
docs_dir |
Source directory for Markdown files (default: docs) |
site_dir |
Build output for mkdocs-build (default: _mkdocs) |
theme.name |
Theme name — currently material |
Theme Customization¶
Logo and Favicon¶
The logo and favicon shown in the sidebar are set in mkdocs.yml:
Colour Palette¶
Add a palette block to the theme section of mkdocs.yml:
See the Material colour reference for the full list of named colours. You can also supply a hex value via CSS (see below).
Fonts¶
Set font: false to use system fonts and avoid loading anything from Google Fonts.
Custom CSS and JavaScript¶
Create override files and reference them in mkdocs.yml:
Place the files under docs/stylesheets/ and docs/javascripts/ respectively. For example, docs/stylesheets/extra.css:
:root {
--md-primary-fg-color: #1a73e8;
--md-primary-fg-color--light: #e8f0fe;
--md-primary-fg-color--dark: #1557b0;
}
Overriding Theme Templates¶
Material supports a custom_dir override mechanism. Create a docs/overrides/ directory and point to it in mkdocs.yml:
Any file placed in docs/overrides/ that matches a path from the Material theme will replace the original. For example, to customise the footer, copy partials/footer.html from the Material theme source into docs/overrides/partials/footer.html and edit it there.
See the Material theme documentation on template overrides for the full list of available partials.
Navigation¶
The page tree is defined under the nav key in mkdocs.yml:
nav:
- Home: index.md
- Getting Started:
- Quick Reference: QUICK_REFERENCE.md
- Demo: DEMO.md
- Reference:
- Architecture: ARCHITECTURE.md
Omitting the nav key causes MkDocs to generate navigation automatically from the docs/ directory structure.
Makefile Variables Reference¶
| Variable | Default | Description |
|---|---|---|
BOOK_OUTPUT |
_book |
Output directory for make book |
MKDOCS_CONFIG |
mkdocs.yml |
Path to the MkDocs config file |
Deployment¶
The reusable rhiza_book.yml workflow builds _book/, uploads it as a generic
book workflow artifact, and — by default — packages it as a GitHub Pages
artifact and deploys it to Pages from the repository's default branch.
GitHub Pages (default)¶
The github-book overlay bundle wires this up out of the box: adopt the bundle
and the workflow deploys to Pages with no further configuration.
Artifact-only mode¶
GitHub Pages requires GitHub Enterprise Cloud for private repositories, which
may be disproportionate for a small private project. The book output is a
portable static site, so the reusable workflow accepts a deploy-pages input
that turns off the Pages-specific artifact upload and deploy job. The generic
book artifact is still uploaded, so a consumer-owned job can download it and
deploy anywhere.
GitHub validates permissions requested by every job in a reusable workflow
before evaluating job conditions. Consequently, an artifact-only caller must
still grant the book job pages: write and id-token: write, even though
the disabled deploy job never receives them at runtime:
permissions:
contents: read
pages: write
id-token: write
jobs:
book:
uses: jebel-quant/rhiza/.github/workflows/rhiza_book.yml@<version>
with:
deploy-pages: false
secrets:
GH_PAT: ${{ secrets.GH_PAT }}
UV_EXTRA_INDEX_URL: ${{ secrets.UV_EXTRA_INDEX_URL }}
permissions:
contents: read
pages: write
id-token: write
deploy:
needs: book
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v8
with:
name: book
path: _book
# Consumer-specific deployment to Cloudflare, Azure, S3, ...
Rhiza does not implement provider-specific deployment: its responsibility is to
build, validate and expose the portable book artifact. Deployment credentials
and provider-specific configuration stay in the consumer repository, which
keeps the interface general and avoids coupling Rhiza to any one host.
Trying an unreleased Rhiza workflow¶
To test an unreleased workflow change, exclude
.github/workflows/rhiza_book.yml in .rhiza/template.yml, add a
consumer-owned replacement workflow, and point its uses: reference at the
branch under test. This limits the experiment to one file. Pointing
template.yml at a work-in-progress branch and running a full sync instead
updates every managed file from that branch.
Remove the exclusion and restore a released Rhiza reference once the feature is available in a release.
Example: Cloudflare Pages¶
One-time Cloudflare setup:
- In Workers & Pages → Create application, select Continue to Pages,
then create a Direct Upload project. Do not use Upload your static
files from the initial screen: it creates a Workers static-assets project,
which
wrangler pages deploycannot deploy to. Give the Pages project a name such asmy-project-book; upload a placeholder file for its first deployment. - Optionally attach a custom domain such as
docs.example.com. - At
dash.cloudflare.com/profile/api-tokens, create a custom scoped token withAccount → Cloudflare Pages → Editfor the relevant account. - Find the account ID in the Account details panel of the Workers & Pages overview.
- Add
CLOUDFLARE_API_TOKENandCLOUDFLARE_ACCOUNT_IDto the consumer repository's GitHub Actions secrets, and addCLOUDFLARE_PAGES_PROJECT(for example,my-project-book) as an Actions variable.
Then in the consumer workflow:
name: "(RHIZA) BOOK"
on:
push:
branches:
- "**"
permissions:
contents: read
pages: write
id-token: write
jobs:
book:
uses: jebel-quant/rhiza/.github/workflows/rhiza_book.yml@<version>
with:
deploy-pages: false
secrets:
GH_PAT: ${{ secrets.GH_PAT }}
UV_EXTRA_INDEX_URL: ${{ secrets.UV_EXTRA_INDEX_URL }}
permissions:
contents: read
# GitHub validates the reusable workflow's disabled Pages job before
# evaluating `deploy-pages`; these permissions are required to start it.
pages: write
id-token: write
deploy-cloudflare:
name: Deploy book to Cloudflare Pages
needs: book
# Publish only the default branch. Feature branches still build and
# validate the book, but do not replace the production documentation.
if: >-
github.ref_name == github.event.repository.default_branch &&
!github.event.repository.fork
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Download Rhiza book artifact
uses: actions/download-artifact@v8
with:
name: book
path: _book
- name: Deploy to Cloudflare Pages
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: >-
pages deploy _book
--project-name=${{ vars.CLOUDFLARE_PAGES_PROJECT }}
If the documentation must stay private, Cloudflare Access can be enabled for the Pages hostname to require authentication via a corporate identity provider, an email-domain rule or an explicit allow-list. That configuration lives entirely on Cloudflare's side; Rhiza neither handles user authentication nor embeds credentials in the generated book.