Static site that renders a Typst document as SVG and/or HTML and displays it in a web page. Deployable as-is on Vercel or Cloudflare Pages.
Live demo: typst2web-demo.vercel.app
Each button targets one specific platform:
- Deploy with Vercel → clones the repo into your GitHub account and sets up a Vercel project that auto-rebuilds on every push.
- Deploy to Cloudflare → does the same thing on Cloudflare Pages / Workers.
Pick whichever one you want; you can also use both (the same repo can be deployed to both platforms in parallel). Note: each button creates an independent copy of this repo in your GitHub account — not a GitHub fork, so there's no upstream link or "Sync fork" relationship.
- On every
git push, the platform (Vercel or Cloudflare) spins up a Linux container - The
build.shscript downloads the Typst binary and compilesdocument.typto SVG - The
public/directory (withindex.html+ the SVGs) is served on the CDN - The home page dynamically loads every page of the document
git clone <this-repo> my-site
cd my-site
# Edit document.typ with your content- Go to vercel.com/new
- Import the repo
- Vercel reads
vercel.jsonautomatically — nothing to configure - Click Deploy
- Go to dash.cloudflare.com → Workers & Pages → Create → Pages → Connect to Git
- Select the repo
- Configure:
- Build command:
bash build.sh - Build output directory:
public
- Build command:
- Click Save and Deploy
The same repo can be deployed to both platforms in parallel without conflict.
If you have Typst installed locally:
bash build.sh
# Then serve the public/ directory
python3 -m http.server -d public 8000
# Open http://localhost:8000Otherwise, just push and check the result on the preview URL.
.
├── document.typ # your Typst content (edit this)
├── build.sh # downloads Typst + fonts and compiles
├── public/
│ └── index.html # display page (loads SVGs dynamically)
├── vercel.json # Vercel config
├── wrangler.toml # Cloudflare config (optional)
└── package.json
build.sh reads the RENDER environment variable to decide which format(s) to produce:
bash build.sh # default: both (SVG + HTML)
RENDER=svg bash build.sh # SVG only (multi-page)
RENDER=html bash build.sh # HTML only (single file, experimental)
RENDER=both bash build.sh # explicit bothWhen both formats are available, public/index.html shows a SVG / HTML toggle in the header. Otherwise the available format is displayed directly. On Vercel / Cloudflare Pages, set RENDER in the build settings → Environment Variables to override the default.
The HTML view is rendered inline with Shadow DOM so the Typst-emitted CSS does not leak into the surrounding page.
- Web page styling: edit the
<style>block inpublic/index.html - Output format: see "Render mode" above, or replace
page-{n}.svgwithdocument.pdfinbuild.shif you prefer an embedded PDF
Fonts are not stored in the repo — build.sh downloads them from the Google Fonts CSS API on every build. The legacy CSS endpoint returns .ttf URLs when called with an old User-Agent, which is exactly what Typst needs. This keeps the repo small (~30 KB) while still using custom typefaces. All three fonts are under the SIL Open Font License:
- EB Garamond — classic serif for body text
- Inter — modern sans-serif for headings and UI
- JetBrains Mono — monospace for code
Files land in fonts/ (gitignored) during the build, and --font-path fonts is passed to Typst so it can find them.
- Find the font on Google Fonts and note its family name
- Add an entry to the
familieslist inbuild.shwith the desired weight/style spec (e.g.400,400i,700) - Use the family name in
document.typ:#set text(font: "Font Family Name")
Remove the font-download block and the --font-path fonts flag from build.sh.