Pilcrow for Eleventy
A plugin that hooks Eleventy's transform pipeline and runs the typesetter over every output page that opts in.
What it does
Once registered, the plugin opens a single headless Chromium for the build and adds an addTransform step that fires for every page Eleventy writes. Pages whose layout wraps their content in <div class="post-body"> have the inner paragraphs replaced by per-line <span class="pt-line"> spans. Pages without that wrapper are passed through untouched, so you can opt content in one layout at a time. Chromium closes when the build finishes. Nothing runs at the reader.
Install
npm install --save-dev pilcrow-eleventy
npx playwright install chromium Playwright is a peer dependency. The Chromium download is roughly 170 MB on first install; subsequent builds reuse the cached binary. The package is published on npm.
Minimal config
In eleventy.config.mjs:
import pilcrowEleventy from 'pilcrow-eleventy';
export default function (eleventyConfig) {
eleventyConfig.addPlugin(pilcrowEleventy);
return {
dir: { input: 'src', output: '_site' },
};
} Then in your post layout, wrap the content in the class the plugin keys on:
<article>
<h1>{{ title }}</h1>
<div class="post-body">
{{ content | safe }}
</div>
</article> That wrapper is the contract. Pages without it are passed through untouched, so adding the plugin to an existing site is non-destructive by construction.
Options
The plugin forwards options straight through to the engine. The interesting one is dropCap; the rest control measurement geometry and almost never need to be set, because the renderer reads font, column width, and line height from the page's own CSS by default.
eleventyConfig.addPlugin(pilcrowEleventy, {
dropCap: true, // false to disable the lede drop cap globally
}); For a per-post opt-out without changing the global default, drop a <meta name="pilcrow:drop-cap" content="false"> tag in the page head. Useful when the lede is a quotation or a list-introduction rather than running prose. The full options reference lives on the API page.
Common pitfalls
The plugin needs Playwright Chromium available at build time, so build hosts that block browser sandboxing or omit Chromium binaries will not work. Vercel, Netlify, Cloudflare Pages, GitHub Actions, and GitLab CI are all confirmed working. If you are deploying inside a locked-down corporate runner, check whether Chromium can be installed before assuming the plugin will run.
The transform only fires on output paths ending in .html; CSS, JSON, and other passthrough formats are ignored. If your layout produces non-HTML output that contains a post-body wrapper for some reason, the plugin will pass it through.
The post-body wrapper has to be present in the rendered output, not just in your template. If your layout chain strips wrapper divs or renames the class, the plugin sees no anchor and the page goes through untouched. The fix is almost always a one-line layout change.
Reference fixture
A working end-to-end fixture lives in the repository at packages/pilcrow-eleventy/test/fixture. It is the same project the plugin's tests run against, so it stays in sync with whatever the current released version supports.