Hello, Quarto. Bye, Zensical.
![]()
![]()
This site used to run on Zensical. It now runs on Quarto.
Why move
Zensical is the spiritual successor to Material for MkDocs, from the same author. The direction is right. The execution is early. Plugin coverage is thin, theming hooks are still shifting, and the documentation lags the code. Fine for a landing page. Not where I want to spend cycles when I’m trying to publish.
Quarto sits in a different place. It is a scientific publishing system first and a static site generator second. That ordering matters. .qmd and .ipynb are first-class inputs. Code executes at render time and the outputs are pinned via freeze. Math, citations, cross-references, and figure numbering are part of the format, not bolted on. The same source renders to HTML, PDF, and reveal.js without a second toolchain.
For a site that will mix prose with notebooks and blog posts, that is the whole game.
The migration
Content was straightforward. Markdown is markdown. Front matter shifted from MkDocs conventions to Quarto’s:
---
title: "Hello, Quarto. Bye, Zensical."
date: "2026-05-23"
categories: [news]
---The blog index is a Quarto listing page. No plugin, no template hacking:
---
title: "Blog"
listing:
contents: posts
sort: "date desc"
type: default
categories: true
feed: true
---Theming is Bootstrap plus SCSS overrides. I kept Litera and added a styles-dark.scss for dark mode tweaks. Highlight styles are split per scheme so code blocks read well in both:
format:
html:
theme:
light: litera
dark: [litera, styles-dark.scss]
highlight-style:
light: github
dark: monokaiCloudflare Pages
This is the part that needed care. Cloudflare Pages does not ship Quarto in its build image. The official path is to install it yourself in the build step.
I pin the version. Floating versions are a great way to wake up to a broken site:
#!/usr/bin/env bash
set -euo pipefail
QUARTO_VERSION="${QUARTO_VERSION:-1.9.37}"
curl -fsSL "https://github.com/quarto-dev/quarto-cli/releases/download/v${QUARTO_VERSION}/quarto-${QUARTO_VERSION}-linux-amd64.tar.gz" \
| tar -xz -C /opt
export PATH="/opt/quarto-${QUARTO_VERSION}/bin:${PATH}"
quarto renderIn the Pages project settings:
- Build command:
./build.sh - Build output directory:
_site - Root directory: project root
A few things worth knowing if you walk this path:
Pin the Quarto version explicitly. Quarto’s HTML output evolves between minor releases. The inline theme-toggle script in particular references DOM nodes that older versions did not emit. If your build image and your local version drift, you can ship a site whose JavaScript throws on load and silently falls back to defaults. Ask me how I know.
Commit _freeze/. Cloudflare’s builders are ephemeral and do not have your Python or R environment. Freezing computational output locally and checking it in means the builder only needs Quarto and pandoc, not your full data stack. Build times drop to seconds.
Skip output-dir surprises. Quarto writes to _site by default. Match Cloudflare’s output directory to that and resist the urge to rename.