Typsite Documentation
Typsite Documentation
1 Introduction
Typsite is a tool for building static websites. It uses pure Typst to write content and processes it through Typsite to generate a fully functional static site.
2 Features
- Standard Typst expressions
- Framework support: hierarchical headings, section templates, sidebar, footer
- Rich text: paragraphs, sections, quotes, code blocks, math formulas, footnotes, page embedding
- Typst math -> Mathml (auto detected math-font)
- Supports modern web standards such as HTML5, CSS3, and JavaScript (ES6+)
- Incremental compilation and real-time preview
3
Introduction to Typst
[typst]
Typst is a modern typesetting system, similar to LaTeX, but designed to be more concise and easier to learn. It is primarily used to create beautifully typeset documents such as academic papers, books, and reports.
You can find the official English documentation here: Typst Document
For a Chinese tutorial on Typst, I highly recommend: The Typst Blue Book
[Oh my, the author is clearly aware that they’re explaining an ontology!].
Typst
🔥has risen!🔥
🚀Did the TeX folks miss the memo?🚀
The rest of this section will introduce Typst & HTML → Typsite
3.1 Typst’s HTML Export Feature
In version
0.13
0.13
, Typst added HTML export capabilities, including an html-export mode and two core functions:
html.elem
html.elem
and
html.frame
html.frame
— using these, we can write Typst documents targeting HTML+CSS output.
3.2 Typsite: A Static Site Generator Based on Typst
Inspired by this, I developed a static site generator in Rust called Typsite.
Currently, Typst’s HTML export:
- Has good support for basic rich text
- Requires users to manually write complex styles using the
html.elemhtml.elemfunction - Cannot automatically convert all Typst ecosystem content into HTML
- For content with complex Typst styles,
html.framehtml.framecan be used to convert them into SVG and embed them into HTML - Only supports single-file HTML output per compilation
For details on supported features and the roadmap, follow this issue: HTML export #5512
Although the official team plans to support automatic typst style → HTML+CSS in the future, this won’t conflict with Typsite. On the contrary, Typst’s development will make Typsite even more useful, because Typsite’s main role is to coordinate interaction between articles and ultimately build a fully functional static website.
4 Installation
Download the binary from the release page
- Use the latest stable Typst (currently tested with 0.15.1)
- Building from source requires Rust 1.89 or newer
Build via Nix & Flakes
- Ensure you’ve enabled
experimental-features = nix-command flakesexperimental-features = nix-command flakes
- Ensure you’ve enabled
git clone https://github.com/Glomzzz/typsite.git
cd typsite
nix build .
git clone https://github.com/Glomzzz/typsite.git
cd typsite
nix build .
5 Initialization
Run
typsite init
typsite init
to initialize a Typsite project in the current directory.
.
├── root --- Typst root directory
│ ├── index.typ --- Main article
│ └── lib/ --- Typsite library files; entry point: lib/lib.typ
├── .typsite --- Typsite configuration directory
│ ├── assets --- Resources (synced to output directory)
│ ├── components --- Component templates
│ ├── themes --- Code highlighting themes
│ ├── rewrite --- Rewrite templates
│ ├── schemas --- Page templates
│ └── options.toml --- Project configuration
├── .cache --- Cache directory
└── publish --- Output directory
.
├── root --- Typst root directory
│ ├── index.typ --- Main article
│ └── lib/ --- Typsite library files; entry point: lib/lib.typ
├── .typsite --- Typsite configuration directory
│ ├── assets --- Resources (synced to output directory)
│ ├── components --- Component templates
│ ├── themes --- Code highlighting themes
│ ├── rewrite --- Rewrite templates
│ ├── schemas --- Page templates
│ └── options.toml --- Project configuration
├── .cache --- Cache directory
└── publish --- Output directory
7 CLI (Command Line Interface)
Usage: typsite <COMMAND>
Commands:
init Initialize a new Typsite project in the specified directory
compile Compile or watch a project; specify input/output [alias: c]
clean Clear cache and output directories
syntect Check the list of supported syntax and code highlighting
help Print this message or help info for a subcommand
Options:
-h, --help Print help
-V, --version Print version info
Usage: typsite <COMMAND>
Commands:
init Initialize a new Typsite project in the specified directory
compile Compile or watch a project; specify input/output [alias: c]
clean Clear cache and output directories
syntect Check the list of supported syntax and code highlighting
help Print this message or help info for a subcommand
Options:
-h, --help Print help
-V, --version Print version info
7.1 init
Initialize a new Typsite project in the specified directory
Usage: typsite init [OPTIONS]
Options:
-d, --dir <DIR> Project root directory [default: ./]
-h, --help Print help
Initialize a new Typsite project in the specified directory
Usage: typsite init [OPTIONS]
Options:
-d, --dir <DIR> Project root directory [default: ./]
-h, --help Print help
7.2 compile
Compile or watch the project with specified input and output directories
Usage: typsite compile [OPTIONS]
Options:
--host <HOST> Serve host [default: localhost]
--port <PORT> Serve port, must be specified to watch mode [default: 0]
--config <CONFIG> Project config [default: ./.typsite]
--cache <CACHE> Cache dir [default: ./.cache]
-j, --jobs <JOBS> Concurrent article exports [default: automatic CPU/Rayon budget]
-i, --input <INPUT> Typst root dir, where your typst files are stored [default: ./root] [aliases: --i]
-o, --output <OUTPUT> Output dir [default: ./publish] [aliases: --o]
-p, --packages <PACKAGES> Packages dir, will be installed to @local and will be synced to @local in watch mode, skip if empty or not found [default: ] [aliases: --p]
-t, --typst <TYPST> Typst executable path [default: typst]
--no-pretty-url
--no-short-slug
-h, --help Print help
Compile or watch the project with specified input and output directories
Usage: typsite compile [OPTIONS]
Options:
--host <HOST> Serve host [default: localhost]
--port <PORT> Serve port, must be specified to watch mode [default: 0]
--config <CONFIG> Project config [default: ./.typsite]
--cache <CACHE> Cache dir [default: ./.cache]
-j, --jobs <JOBS> Concurrent article exports [default: automatic CPU/Rayon budget]
-i, --input <INPUT> Typst root dir, where your typst files are stored [default: ./root] [aliases: --i]
-o, --output <OUTPUT> Output dir [default: ./publish] [aliases: --o]
-p, --packages <PACKAGES> Packages dir, will be installed to @local and will be synced to @local in watch mode, skip if empty or not found [default: ] [aliases: --p]
-t, --typst <TYPST> Typst executable path [default: typst]
--no-pretty-url
--no-short-slug
-h, --help Print help
7.3 clean
Clear cache and output directories
Usage: typsite clean [OPTIONS]
Options:
--input <INPUT> Protected Typst source directory [default: ./root]
--config <CONFIG> Protected configuration directory [default: ./.typsite]
--force Allow cleaning unmarked legacy directories after path checks
-o, --output <OUTPUT> Output directory [default: ./publish]
-c, --cache <CACHE> Cache directory for raw Typst HTML [default: ./.cache]
-h, --help Print help
Clear cache and output directories
Usage: typsite clean [OPTIONS]
Options:
--input <INPUT> Protected Typst source directory [default: ./root]
--config <CONFIG> Protected configuration directory [default: ./.typsite]
--force Allow cleaning unmarked legacy directories after path checks
-o, --output <OUTPUT> Output directory [default: ./publish]
-c, --cache <CACHE> Cache directory for raw Typst HTML [default: ./.cache]
-h, --help Print help
7.4 syntect
View the list of syntax highlighting and supported languages
Usage: typsite syntect [OPTIONS]
Options:
--config <CONFIG> Config path [default: ./.typsite]
-h, --help Print help
View the list of syntax highlighting and supported languages
Usage: typsite syntect [OPTIONS]
Options:
--config <CONFIG> Config path [default: ./.typsite]
-h, --help Print help
7.5 Build parallelism
Typsite uses Rayon to hash independent files, check export caches, parse article HTML, and render pages in parallel. Typst exports run in a separate bounded Rayon pool: the automatic limit is the available CPU budget (also respecting the Rayon pool size). Each Typst subprocess receives a share of that CPU budget through its own
--jobs
--jobs
option, rather than letting every subprocess spawn a full machine’s worth of workers.
typsite compile --jobs 4
# Low-memory or export debugging: one article subprocess at a time.
typsite compile --jobs 1
typsite compile --jobs 4
# Low-memory or export debugging: one article subprocess at a time.
typsite compile --jobs 1
-j
-j
is an alias for
--jobs
--jobs
; the value must be positive. This setting controls simultaneous article exports, not all Rayon work. Use
RAYON_NUM_THREADS
RAYON_NUM_THREADS
to tune Rayon hashing/parsing/rendering separately. An explicit high
--jobs
--jobs
limit can increase memory use; it is still bounded by the number of dirty articles. No export pool is created for true no-ops.
Packages are prepared before exports start. Workers produce independent artifacts, then the build joins them and records results in stable source order. Graph resolution, dependency-ordered metadata, cache/ownership checkpoints, and stale deletions stay ordered for correctness. Independent output files publish in parallel with atomic renames and data syncing; parent directories are synced once per batch. Verified no-ops skip configuration parsing, validated highlighting resources have a content-keyed cache, and shared dependencies are checked once per export batch. Changing
--jobs
--jobs
alone does not invalidate the cache or change site bytes.
8 RSS feed and sitemap
RSS is opt-in. The article flag
rss
rss
defaults to
false
false
, and the bundled
base_url
base_url
is empty. To publish a feed, configure the site URL and select articles with
#rss(true)
#rss(true)
on a collection page. Do not set the global article default to true.
8.1 1. Enable feed generation
Set the public site URL in
.typsite/options.toml
.typsite/options.toml
to generate RSS 2.0 and a sitemap:
[site]
base_url = "https://example.org"
title = "My site"
description = "Notes and articles"
rss_path = "/rss.xml"
sitemap_path = "/sitemap.xml"
rss_limit = 20
rss_content = "summary" # "summary" or "full"
[site]
base_url = "https://example.org"
title = "My site"
description = "Notes and articles"
rss_path = "/rss.xml"
sitemap_path = "/sitemap.xml"
rss_limit = 20
rss_content = "summary" # "summary" or "full"
Do not add a second
[site]
[site]
section; edit the existing one. Replace the example URL with your actual public URL, then run
typsite compile
typsite compile
. The files are written beneath the output directory. Every generated page receives an RSS autodiscovery link in its HTML head; readers can subscribe to
https://example.org/rss.xml
https://example.org/rss.xml
.
8.2 2. Select articles with a container
Article metadata has a boolean
rss
rss
option, defaulting to
false
false
. Mark a collection page with
#rss(true)
#rss(true)
, then directly embed the articles to publish:
#import "/lib/lib.typ": *
#show: schema.with("page")
#title[My feed collection]
#rss(true)
= #embed("./first-post.typ")
= #embed("./second-post.typ")
#import "/lib/lib.typ": *
#show: schema.with("page")
#title[My feed collection]
#rss(true)
= #embed("./first-post.typ")
= #embed("./second-post.typ")
Only those directly embedded articles become feed items. The marked collection page itself is excluded, even if another collection embeds it. The marker is not inherited by embedded articles. Nested embeds are not selected as separate entries; their content still appears inside a selected article in full mode. Citations, parent metadata, and graph-only child declarations do not select items. Multiple containers contribute a union of entries, with each article appearing only once.
#rss(false)
#rss(false)
makes a page an ordinary article again; it can still be included if a marked container embeds it. With no marked containers (or no eligible direct embeds), the enabled feed is empty. Date ordering and
rss_limit
rss_limit
apply after selection. The sitemap still lists all compiled articles.
Both demo homepages are marked containers. They directly embed the article guide and Typst introduction in each language, so the demo feed has four entries, not every page. For older customized libraries, import
rss
rss
from
@local/typsite:0.1.0
@local/typsite:0.1.0
or merge the new
root/lib/lib.typ
root/lib/lib.typ
import.
8.3 3. Try it in this demo
After setting
base_url
base_url
, run these commands from the initialized demo directory:
typsite compile
typsite compile --port 8080
typsite compile
typsite compile --port 8080
Inspect
publish/rss.xml
publish/rss.xml
, or open
http://localhost:8080/rss.xml
http://localhost:8080/rss.xml
while preview is running. Deploy the output and subscribe using your public URL, such as
https://example.org/rss.xml
https://example.org/rss.xml
; the preview address is only for local checks.
No file? Check
base_url
base_url
,
rss_path
rss_path
, and
rss_limit
rss_limit
. Empty feed? Check for a marked container with eligible direct embeds. Keep
[default_metadata.options].rss = false
[default_metadata.options].rss = false
;
#rss(true)
#rss(true)
belongs on the collection, not on the posts you want to publish. A self-contained upgrade walkthrough is in
the 0.1.8 RSS migration instructions
.
8.4 Item content and dates
-
summarysummaryincludes a plain-text description, taking the first nonemptydescriptiondescription,summarysummary, orabstractabstractmetadata value. It does not invent an excerpt when these are absent. -
fullfulladditionally includes the composed article HTML incontent:encodedcontent:encoded, including embedded articles but not the page schema, navigation, sidebar, or reference/backlink footer. Ordinary links and image URLs become absolute. Scripts are omitted; feed readers may not display SVG, MathML, interactive elements, or site-specific CSS exactly like the website. - Titles use
page-titlepage-title, thentitletitle. Articles are ordered byupdatedupdated,lastmodlastmod, thendatedate, newest first, with URLs breaking ties.pubDatepubDateuses the publicationdatedate, falling back to the modification time. - Dates accept
YYYY-MM-DDYYYY-MM-DD,YYYY-MM-DD HH:MM[:SS]YYYY-MM-DD HH:MM[:SS](UTC), RFC 3339, or RFC 2822. Invalid or unknown dates are omitted rather than emitting invalid RSS dates. - An empty
base_urlbase_urldisables both outputs. An emptyrss_pathrss_pathorrss_limit = 0rss_limit = 0disables RSS only. An emptysitemap_pathsitemap_pathdisables only the sitemap. Disabled or renamed generated files are cleaned up through the ownership journal. - Changing feed settings only recomposes outputs; unchanged articles are not re-exported with Typst.
--no-pretty-url--no-pretty-urlis reflected in article links.
Add metadata to an article with the existing helpers:
#title[An article]
#date[2026-03-02 18:25]
#metacontent("summary")[A short introduction for feed readers.]
#metacontent("updated")[2026-03-03T09:00:00Z]
#title[An article]
#date[2026-03-02 18:25]
#metacontent("summary")[A short introduction for feed readers.]
#metacontent("updated")[2026-03-03T09:00:00Z]
9 Architecture & Flow
The diagram has three lanes: read them top to bottom, each left to right. HIT reuses raw HTML; MISS invokes Typst. An unchanged published site takes the no-op exit at step 03; only dirty builds drop into the build lane for parsing, graph resolution, and whole-page composition. Tags mark parallel stages and the two independent checkpoints (A for exports, B for publication ownership), and the bottom red band explains recovery. On small screens, scroll within the diagram to read the details.
Rayon parallelizes independent hashes, article parsing, page rendering, and bounded Typst exports; package setup and publication checkpoints remain ordered. The cache stores raw Typst HTML and actual dependency hashes, not old relationships or rendered fragments. Dirty builds recompose all pages but write only changed bytes; true no-ops neither write output nor reload preview clients. Publication is atomic per file, not for the whole site; fix a reported failure and rerun to recover. See Migrating to Typsite 0.1.8 for migration and output-ownership details.
10 Configuration
You can view all default configurations here:
Based on these, you can fully customize your entire site.
- schema: Page templates, handling page structure
- components / rewrites: Components/Rewriters, build up the page content
- assets: Resource files, automatically synced during compilation
- themes: Code highlighting files
- syntaxes: Code syntaxes files
11
Article
[article]
11.1 Metadata
11.1.1 Page Settings
11.1.2 Meta Content
11.1.3 Article Relations
11.2 Sidebar
11.3 Main Content
11.3.1 Headings
11.3.2 Paragraphs
11.3.3 Breadcrumbs
11.3.4 Embeds
11.3.5 Footnotes
11.3.6 Links
11.3.7 Formulas
11.3.8 Inline Content
11.3.9 Code
11.3.9.1 Theme
11.3.9.2 Syntax
11.3.10 Styles
11.3.10.1 Alignment
11.3.10.2 Highlight
11.3.10.3 Colored Text
11.3.10.4 Bold
11.3.10.5 Italic
11.4 Footer
11.4.1 Backlinks
11.4.2 References
Backlinks
Backlinks
Migrating to Typsite 0.1.8 [migrate-to-018]
Migrating to Typsite 0.1.8 [migrate-to-018]
Typsite 0.1.8 replaces the build engine, fixes stale incremental output, and supports the latest stable Typst. Existing valid articles, templates, configuration keys, and CLI options remain supported. This guide covers the changes that need attention when upgrading from 0.1.7.
If you are upgrading from an earlier release, also read Migrating to Typsite 0.1.7 .
1 Upgrade checklist
Back up your articles,
root/libroot/lib, and.typsite.typsite, especially any custom templates or helpers.Install Typsite 0.1.8 and the latest stable Typst. This release has been tested with Typst 0.15.1. Older Typst releases are not a compatibility target.
Generate a separate reference project; do not initialize over your existing site:
typsite init --dir ../typsite-018-referencetypsite init --dir ../typsite-018-referenceCompare that project’s
root/libroot/liband.typsite.typsitewith yours. Merge the updated helpers without overwriting your customizations.Run your usual compile command. Old internal caches are automatically treated as cache misses; a manual clean is not normally necessary.
typsite --version typst --version typsite compiletypsite --version typst --version typsite compileCheck both the rendered site and the command’s exit status before deploying. A failed build now exits with a nonzero status.
2 Site helpers and Typst
2.1 Update inline-math
Merge the updated
root/lib/site.typ
root/lib/site.typ
from the reference project. The
inline-math
inline-math
helper now runs in a contextual evaluation, queries footnote labels, and passes them through to the SVG renderer. Both inline and block fallback are supported:
#inline-math($a/b$)
#inline-math($sum_(i=1)^n i$, block: true)
#inline-math($a/b$)
#inline-math($sum_(i=1)^n i$, block: true)
Your existing call sites do not need a new signature. Typsite passes the HTML feature flag and
html-frames
html-frames
input to Typst automatically.
2.2 Keep the bundled package import
The Typsite executable is version 0.1.8. The bundled Typst package keeps its existing identity:
#import "@local/typsite:0.1.0": *
#import "@local/typsite:0.1.0": *
Do not change this import to
@local/typsite:0.1.8
@local/typsite:0.1.8
. The executable installs its bundled package before an export that needs it.
2.3 Build the bundled demo
The initialized demo includes these migration pages, its templates, fonts, and SVG examples. It does not require preview-package downloads. From the reference project directory:
typsite compile
typsite compile --port 8080
typsite compile
typsite compile --port 8080
The second command starts preview mode. Open
http://localhost:8080/
http://localhost:8080/
or
/en/
/en/
. External music players and web-font links in the content examples still need a browser network connection; they are not build dependencies.
3 Cache and output ownership
The cache now stores raw Typst HTML and fingerprints of the files Typst actually read. Imports and included files invalidate the appropriate exports. Parsed relationships and rendered fragments are not restored from old caches.
When publication is dirty, Typsite rebuilds the current relationship graph and recomposes all pages. Only changed output bytes are written. Removing a citation removes its old backlink; deleting or renaming an article removes its old owned output.
The output directory contains a separate ownership journal:
publish/.typsite-outputs.json
publish/.typsite-outputs.json
Keep this file. It is not a disposable cache. It lets Typsite remove stale generated files while preserving unrelated files. If it is corrupt, the build refuses to guess which files may be deleted. Back it up before repairing it; deleting it explicitly relinquishes ownership of previous outputs.
Outputs created before this journal existed are not automatically claimed or removed. If an old, deleted page remains after upgrading, remove that known obsolete file yourself, or explicitly clean the output directory after reviewing its contents.
3.1 Safer clean
typsite clean
typsite clean
validates both roots before deleting anything, takes the build locks, and refuses source/configuration overlap. Nonempty legacy directories without ownership markers require an explicit opt-in:
# Review these directories first: clean removes their contents.
typsite clean --cache ./.cache --output ./publish --force
# Review these directories first: clean removes their contents.
typsite clean --cache ./.cache --output ./publish --force
If your source or configuration roots are nondefault, pass them too so they are protected:
typsite clean --input ./content --config ./config \
--cache ./build-cache --output ./public --force
typsite clean --input ./content --config ./config \
--cache ./build-cache --output ./public --force
--force
--force
permits unmarked legacy directories; it does not bypass path-safety checks or active build locks. Lock files may remain after cleaning. Do not delete
.typsite.lock
.typsite.lock
while a build or preview process is running.
4 Stricter validation
Previously ignored errors can now stop a build. Fix or remove invalid resources rather than relying on them being skipped:
- Schemas, components, and rewrite HTML must have complete
<head>...</head><head>...</head>and<body>...</body><body>...</body>envelopes. A deliberately empty<head/><head/>or<body/><body/>is allowed. - Malformed themes, syntax definitions, syntax metadata, and rewrite resources are errors, even if unused. Duplicate resource identities are rejected.
- A page cannot explicitly name itself as its parent or embed itself. Cycles in parent inheritance, embeds, or metadata dependencies are rejected instead of hanging. Ordinary mutual citations and self-citations remain allowed.
- Source, configuration, cache, and output roots must not overlap; package sources must not overlap cache or output roots. Output collisions, case-only collisions, escaping paths, and symlinked managed output paths are rejected. Spaces and bracket characters in directory names are supported literally.
-
.typsite.lock.typsite.lockand.typsite-outputs.json.typsite-outputs.jsonare reserved output names, including case variants and descendants beneath those names.
5 Packages and reproducibility
--packages
--packages
still names a directory of local package sources, not a Typst namespace. Invalid package names/versions and duplicate identities are rejected before installation.
For an isolated namespace, set
TYPST_PACKAGE_PATH
TYPST_PACKAGE_PATH
; packages will be installed beneath
local/<name>/<version>
local/<name>/<version>
. Typsite also honors
TYPST_PACKAGE_CACHE_PATH
TYPST_PACKAGE_CACHE_PATH
. For example, in a POSIX shell:
export TYPST_PACKAGE_PATH="$PWD/.typst-packages"
export TYPST_PACKAGE_CACHE_PATH="$PWD/.typst-package-cache"
typsite compile
export TYPST_PACKAGE_PATH="$PWD/.typst-packages"
export TYPST_PACKAGE_CACHE_PATH="$PWD/.typst-package-cache"
typsite compile
Keep these directories separate from the source, configuration, build cache, and output roots. Without an override, the default shared package installation behavior is retained. Use project fonts and a fixed
SOURCE_DATE_EPOCH
SOURCE_DATE_EPOCH
when you need reproducible exports; changes to system fonts or undeclared external inputs may require discarding the build cache.
6 Parallel builds and –jobs
Independent file hashes, article parsing, and page rendering now use Rayon. Typst exports run concurrently with an automatic upper bound from the available CPU/Rayon budget (the earlier fixed four-article cap is removed). Each Typst subprocess receives a share of the CPU budget. Set
typsite compile --jobs 1
typsite compile --jobs 1
to serialize article exports on low-memory machines, or
--jobs 4
--jobs 4
to set an explicit limit (
-j
-j
is an alias; values must be positive).
--jobs
--jobs
does not control all Rayon work; use
RAYON_NUM_THREADS
RAYON_NUM_THREADS
to tune hashing/parsing/rendering. Packages are prepared before workers start, results are collected in stable source order, and all workers finish before checkpoint/publication. Graph/metadata ordering, stale deletions, and publication ownership remain protected. Independent output files publish in parallel with atomic renames and data syncing. Disposable caches now use checksummed binary manifests with shared dependency sets, plus a content-keyed highlighting-resource cache; old formats rebuild automatically. Verified no-ops still hash-check actual inputs/artifacts/outputs but no longer reparse all configuration. Installed local packages are fingerprinted before export, avoiding unnecessary verification passes; newly discovered external inputs still need verification. Changing concurrency alone needs no cache clean and produces the same output bytes.
7 RSS feed configuration
RSS 2.0 supports summaries or full article content. Setup has two separate parts: enable feed generation in the site configuration, then choose articles through a marked collection. The article metadata
rss
rss
defaults to false; setting the site URL alone does not select any articles.
7.1 Step 1: Configure the site
Edit the existing
[site]
[site]
section in
.typsite/options.toml
.typsite/options.toml
; do not append a duplicate section. Replace the example URL with the public address where your site will be deployed:
[site]
base_url = "https://example.org"
title = "My site"
description = "Notes and articles"
rss_path = "/rss.xml"
rss_limit = 20
rss_content = "summary" # "summary" or "full"
sitemap_path = "/sitemap.xml"
[site]
base_url = "https://example.org"
title = "My site"
description = "Notes and articles"
rss_path = "/rss.xml"
rss_limit = 20
rss_content = "summary" # "summary" or "full"
sitemap_path = "/sitemap.xml"
Keep
rss = false
rss = false
under
[default_metadata.options]
[default_metadata.options]
(or omit it). This is the per-article default, not a switch under
[site]
[site]
. Opt in on individual collection pages instead of setting every article to true.
7.2 Step 2: Mark a collection and embed its entries
Merge the new
rss
rss
import in
root/lib/lib.typ
root/lib/lib.typ
, or import it directly from the bundled package as below. For example, create
root/feed.typ
root/feed.typ
using two existing demo articles:
#import "/lib/lib.typ": *
#import "@local/typsite:0.1.0": rss
#show: schema.with("page")
#title[Feed collection]
#rss(true)
= #embed("./typst.typ")
= #embed("./article.typ")
#import "/lib/lib.typ": *
#import "@local/typsite:0.1.0": rss
#show: schema.with("page")
#title[Feed collection]
#rss(true)
= #embed("./typst.typ")
= #embed("./article.typ")
This selects
typst.typ
typst.typ
and
article.typ
article.typ
, not
feed.typ
feed.typ
. In your own site, replace these paths with your articles. Only direct embeds are selected; nested embeds, citations, parent links, and graph-only child declarations do not add entries. Multiple containers contribute a deduplicated union. Marked containers are always excluded, even when embedded by another container; their marker is not inherited by their children.
#rss(false)
#rss(false)
removes a container marker, not an item selected by another container.
7.3 Step 3: Build and subscribe
typsite compile
typsite compile --port 8080
typsite compile
typsite compile --port 8080
The first command writes
publish/rss.xml
publish/rss.xml
(or your configured output/path). The second serves it at
http://localhost:8080/rss.xml
http://localhost:8080/rss.xml
for inspection. Readers should subscribe to your deployed public URL, such as
https://example.org/rss.xml
https://example.org/rss.xml
, not the localhost preview address. Each generated HTML page includes an RSS autodiscovery link.
The demo’s two homepages already use
#rss(true)
#rss(true)
. With
base_url
base_url
set, their direct embeds produce four entries: the article guide and Typst introduction in both languages. The additional
feed.typ
feed.typ
above selects existing entries again, without duplicating them. Homepages, migrations, and example pages are not automatically included. The sitemap still includes all compiled articles.
7.4 Content mode and common setup problems
-
rss_content = "summary"rss_content = "summary"is the default: use the first nonemptydescriptiondescription,summarysummary, orabstractabstractmetadata. Add#metacontent("summary")[A short introduction.]#metacontent("summary")[A short introduction.]in the selected article; missing summaries do not exclude it. -
rss_content = "full"rss_content = "full"additionally includes composed article HTML without page navigation, sidebars, or reference/backlink footers. Embedded content remains within its selected article. Feed-reader support for SVG, MathML, and site-specific CSS varies. - No
rss.xmlrss.xml: check thatbase_urlbase_urlis nonempty,rss_pathrss_pathis nonempty, andrss_limitrss_limitis greater than zero. The default path and limit remain/rss.xml/rss.xmland 20. An invalid nonempty site URL fails validation. - An empty feed: check
#rss(true)#rss(true)and actual direct#embed(...)#embed(...)calls. Setting only[site].base_url[site].base_urlis not enough, andrss = falserss = falseis not an item opt-out. - RSS dates use RFC 2822, not ISO timestamps. Date-only and
YYYY-MM-DD HH:MM[:SS]YYYY-MM-DD HH:MM[:SS]metadata use UTC; RFC 3339/RFC 2822 offsets are normalized to UTC. Invalid dates are omitted, and titles/summaries are extracted as text rather than exposing HTML tags.
More settings and article metadata examples are in the homepage’s RSS section .
8 Preview and failure recovery
Preview still uses a nonzero
--port
--port
. Every connected client observes the same build revision. A true no-op does not reload browsers. Export, parse, or render failures keep the last successfully published pages; successful repair triggers a reload. Ctrl-C waits for the in-flight build before shutting down.
Successful exports can be reused after a later publication failure. Fix the reported error and rerun the same command. Publication is atomic per file, not for the whole site: a failed publication may leave a mixture of complete old and new files, which a normal rerun repairs. Use a separate deployment step if you need an all-or-nothing site switch.