Manual
Typstatic
Page status: seedling
Contents
Typstatic is pre-alpha!
Everything changes all the time, everything breaks all the time, and most of the time nobody tells you anything about that. Just like life.
This website is very fragmentary, broken in many places, and sometimes misleading and out of date.
Be patient, Typstatic in development (2026-08). When it’s ready for public use it will be announced on the forum and this message will be removed.
1. Folder structure
1.1. pages.yaml
All fields within a page definition are optional:
assets(sequenceof stringscalars)A list of files in the page’s directory to be copied to the output folder.List only files you want to be copied as-is. Assets used only in the process of the production of the page (e.g. a
YAMLorJSONfile read in order to produce a table) should not be listed. The order of the list bears no meaning. Omit if no such assets are needed.Example value:
assets: - "corpus.webp" - "typst.svg"The
corpus.webpimage used at the top of this page is such an asset.langs(sequenceof stringscalars)A list of languages in which versions of the page are written, as ISO 639-3 codes. The order of the list bears no meaning. If this field is omitted the page is assumed to be written in the default language.
Example value (for a page with versions written in English and Hebrew):
langs: - eng - hebSee the English, Hebrew and Esperanto pages about the Fibonacci sequence as examples.
output-formats
2. Page structure
Pages can be constructed in one of two ways, with a trade-off: one is hacky but with less boilerplate, and the other is more proper but has more boilerplate.A note for the technically-inclined. In the hacky way the file is read and evaluated, and the special variables and functions which are not defined within the file itself are included into the scope. In the proper way the file is imported and the content function, which is defined in the page, is called (and the typstatic-meta variable is provided as an argument). The mechanism for distinguishing between the two types is admittedly hacky in itself and may break in future versions of Typst (suggestions/patches for better methods are welcome): the file is evaluated and the decision is made on whether a regex indicates there is any actual content in the evaluated result (ergo hacky) or not (only definitions, ergo proper). In both the page has with a meta dictionary (see below), and the main difference is in how the actual content of the page is represented:
- In the hacky way it’s represented in the normal way you write Typst document: as the top-level content of the file. Why is it hacky then? Because some variables and functions you use in the page’s file are not defined or imported in the file in any way, which makes it an invalid Typst file, which may cause your editor to complain about unknown variables etc.
- In the proper way the it’s contained within a dedicated function (
content), so that the file has only two definitions without any top-level content: one is of ametadictionary and one of acontentfunction.
For the sake of clarity here, are two minimal working examples:
The hacky, more succinct way:
#let meta = ( title: [A very interesting title], ) // Note that `typstatic-meta` is not defined anywhere within the file itself #show: init.with(meta, typstatic-meta, yaml("/pages.yaml")) _Very_ interesting content!The proper, more verbose way:
#let meta = ( title: [A very interesting title], ) #let content(typstatic-meta) = [ #import "@local/typstatic:0.0.1": init, themes #import themes.at(typstatic-meta.theme): * #show: init.with(meta, typstatic-meta, yaml("/pages.yaml")) _Very_ interesting content! ]
You can choose either way, and there’s no need for all pages to be of one kind.
2.1. The meta dictionary
Metadata is used both for the construction of the page containing it and for components in other pages, such as indices, which use data from other pages.
Obligatory fields:
title(content)The title of the page, to be used for creating the top header (
h1) and for the use of indices and similar elementsExample values:
[A novel proof of the Pythagorean theorem][A novel proof that $a^2 + b^2 = c^2$]
Optional fields:
simple-title(string)- The
titlefield is of the typecontent, which means you can in theory do all kinds of wacky Typst stuff in it. But there are situations where a simple string title is needed, such as for the HTML<title>tag, which sets the title of the tab in the browser. Thetitlefield is used as-is wherever possible, and it’s converted to a string wherever needed, but in cases such a conversion is not possible or the result is not satisfactory, you can provide thesimple-titlefield, which will be used instead of the automatic conversion where a string is needed.
Example value:
"A noval proof that in a right triangle the area of the square whose side is the hypotenuse is equal to the sum of the areas of the squares on the other two sides"
header(content)- When provided, the
headerfield replaces the top header (h1) derived from thetitlefieldTake note that even if you have a customheader, you still have to provide atitle.. This is useful when you want to have a custom design for the page’s header; for example, home pages usually look different to internal, regular pages. This field is used only by the current page, and should not be accessed by other pages. published(datetimeorstring)- The date when the page was published on the website. It can be either a
datetime(e.g.datetime(year: 1984, month: 5, day: 15)) or astringin the formatYYYY-MM-DDOmitting leading zeroes is supported; e.g."1984-5-15"is valid, but personally I think it’s hideous… (e.g."1984-05-15"). updated(datetimeorstring)- The date of the last update of the page. Should not be defined if the pages hasn’t been updated. If the page has been updated multiple time, change the value of the
updatedfield. Format-wise it behaves the same aspublished. summary(content)- A short summary (tl;dr) of the page’s content. Since it’s shown in page lists and the like, I’d suggest keeping it short, perhaps something like old-school tweets (≤140 characters).
tags(array)TagsTypstatic is indifferent to the actual names used. Use whatever naming convention you see fit; I suggest Wikipedia’s convention as a rule of thumb. (keywords) that describe the page. They are an array of strings which can contain basically any character (including spaces and commas) and are case-sensitive.
Example values:
("Typst", "static site generators", "manuals")This website doesn’t have enough pages to justify using tags, but if it was a part of a larger website this page could benefit from these tags.("collective intelligence", "computer jargon", "information retrieval techniques", "knowledge representation", "metadata", "reference", "Web 2.0")For an article about tags (actually taken from Wikipedia).
status(string)