foliate

|200

A minimal static site generator that turns a markdown vault (e.g., Obsidian notes) into a static HTML website.

Why

I’ve been keeping a collection of markdown notes that include research ideas, paper summaries, reading notes, how-tos, or blog-like posts (whatever you call it—a wiki, Zettelkasten, hypercard, … see Ideas of connected ideas). This works as a central place for my personal knowledge.

At the same time, I have been managing my homepage using Jekyll and GitHub Pages. This is a fine solution, but there has always been this nagging friction. It arises when I try to publish some of my pages in my wiki: should I copy the file to my homepage and publish as blog? But then this creates duplicates. Do I create a totally separate wiki site just for these? I did that, but it’s annoying to manage two totally separate system as my “homepage”.

So I always wanted to have a more integrated solution for this issue—a system for publishing both my homepage and wiki pages.

There are some existing options:

What I wanted is a unified content management (markdown files + obsidian) and a tool that I can simply point at my existing vault, tell it which pages are public, and get a website. No restructuring. No copying files into a separate project. And the vault acting as the site source. Update a markdown file, I rebuild, and it’s live.

That’s foliate.

Key ideas

Installation

uv tool install foliate

Or run it directly without installing:

uvx foliate build

Quick start

From inside your vault:

uvx foliate init    # creates .foliate/config.toml
uvx foliate watch   # watch changes, rebuild, and serve locally
uvx foliate build   # generates site to .foliate/build/

That’s it. Edit .foliate/config.toml to set your site name, URL, and navigation. Mark pages as public by adding frontmatter:

---
public: true
published: true
---

Then rebuild.

Visibility system

Foliate’s visibility model is intentionally simple:

Frontmatter Result
(nothing) Private. Not built.
public: true Built. Accessible via direct URL. Hidden from listings.
public: true, published: true Built. Visible in listings, search, and feed.

This lets you share work-in-progress pages by link without cluttering your public index.

Directory conventions

Special directories use an underscore prefix:

Directory Behavior
_homepage/ Content deployed to site root (/) instead of /wiki/
_private/ Always ignored, regardless of frontmatter

Everything else — markdown files, nested folders, whatever structure you already have — maps to /wiki/Your/Path/.

Configuration

.foliate/config.toml controls everything. Key sections:

[site]
name = "My Wiki"
url = "https://example.com"
author = "Your Name"

[build]
wiki_prefix = "wiki"          # URL prefix for wiki content
home_redirect = "about"       # Where / redirects to
ignored_folders = ["_private"] # Folders to skip

[nav]
items = [
    { url = "/about/", label = "About" },
    { url = "/wiki/Home/", label = "Wiki" },
]

[feed]
enabled = true
items = 20
window = 30   # days to include

Atom feed

Foliate generates an Atom feed at /feed.xml for published wiki content. It distinguishes between new pages (individual entries) and recently updated pages (a single digest entry). Configure the time window and entry count in [feed].

Deployment

Built-in deployment to GitHub Pages:

foliate deploy             # rsync to target repo, commit, push
foliate deploy --dry-run   # preview without executing

Configure in [deploy]:

[deploy]
method = "github-pages"
target = "../my-site.github.io"
exclude = ["CNAME", ".gitignore"]

Watch mode

For local development:

foliate watch

This builds, starts a local server, and auto-rebuilds on file changes.

CLI reference

foliate init              # Create .foliate/config.toml
foliate build             # Build site
foliate build --force     # Force full rebuild
foliate build --serve     # Build + local server
foliate watch             # Build + serve + auto-rebuild
foliate deploy            # Deploy to configured target
foliate deploy --dry-run  # Preview deployment
foliate clean             # Remove build/ and cache/