Stalwart Documentation and Website
  • MDX 42.2%
  • Astro 38.9%
  • Vue 6.4%
  • JavaScript 5.9%
  • CSS 3.1%
  • Other 3.5%
Find a file
2026-07-06 14:58:03 +02:00
.vscode Updated clustering diagrams 2025-12-26 17:31:38 +01:00
public Proxy documentation 2026-06-08 17:43:42 +02:00
scripts Migrate site from Docusaurus to Astro 2026-05-07 07:13:27 +02:00
slides Updated slides 2026-05-10 17:26:23 +02:00
src DKIM2 announcement 2026-07-06 14:58:03 +02:00
.gitignore Migrate site from Docusaurus to Astro 2026-05-07 07:13:27 +02:00
.nvmrc Update node version 2026-05-07 07:25:12 +02:00
astro.config.mjs Proxy documentation 2026-06-08 17:43:42 +02:00
CLAUDE.md Migrate site from Docusaurus to Astro 2026-05-07 07:13:27 +02:00
package-lock.json Update node version 2026-05-07 07:25:12 +02:00
package.json Updated slides 2026-05-10 17:26:23 +02:00
README.md Migrate site from Docusaurus to Astro 2026-05-07 07:13:27 +02:00
tsconfig.json Migrate site from Docusaurus to Astro 2026-05-07 07:13:27 +02:00
wrangler.toml Migrate site from Docusaurus to Astro 2026-05-07 07:13:27 +02:00

Stalwart Website

The marketing site, documentation, and blog for Stalwart. Built with Astro 6 and Starlight; deployed as a static site to Cloudflare Pages.

Stack

  • Marketing pages (/, /pricing, /about, /legal/*, etc.) are Astro pages driven by YAML/Markdown content collections under src/content/pages/ and src/content/legal/.
  • Documentation (/docs/...) is rendered by Starlight from src/content/docs/docs/. The previous release line lives at src/content/docs/docs/0.15/ and is served at /docs/0.15/....
  • Blog (/blog, /blog/<post>) is the starlight-blog plugin reading posts from src/content/docs/blog/.
  • Search is Pagefind, the offline static-site search baked into Starlight. The index is rebuilt on every npm run build. No third-party service or API key needed.
  • Per-post OG images are generated by astro-og-canvas at /og/blog/<slug>.png and referenced from <meta property="og:image"> on each blog post.
  • View Transitions (smooth cross-page nav) are enabled site-wide via Astro's <ClientRouter />.

Local development

Requirements: Node.js 20+ (set in package.json engines).

npm install            # one-time, installs Astro + Starlight + plugins
npm run dev            # http://127.0.0.1:8787 with hot reload

npm run dev watches every Markdown, Astro and YAML file. Edits reload in the browser within a second; structural changes (new files, frontmatter schema changes) may require a manual reload.

Other useful scripts:

npm run build          # production build to dist/, runs link validation
npm run preview        # serve dist/ at http://127.0.0.1:8787 to verify

Authoring docs

Drop new pages into src/content/docs/docs/<section>/<page>.md. Frontmatter must include at least a title:. Optional helpful fields:

---
title: My new page
description: One-line summary used for SEO and search results.
sidebar:
  order: 5            # position within the parent group
  badge: New          # appears in the sidebar
---

To rename a directory's sidebar label or change ordering, drop a _meta.yml into that directory (starlight-auto-sidebar docs):

label: Storage settings
order: 5

Admonitions (notes, tips, warnings) use the same triple-colon syntax as before:

:::tip Enterprise feature
This feature ships with the Enterprise edition.
:::

Internal doc links use absolute paths without the .md suffix: [Storage](/docs/storage/overview).

Authoring blog posts

Add src/content/docs/blog/<post-slug>.mdx (or a folder with index.mdx if the post has its own assets). Required frontmatter:

---
title: Post title
date: 2026-05-01
authors: [mdecimus]      # keys are defined in astro.config.mjs starlightBlog config
tags: [release, jmap]
excerpt: |
  One paragraph teaser shown on the index, in tag pages, and in the RSS feed.
---

Reading time is computed automatically.

Deployment (Cloudflare Pages)

The site is a static export. Cloudflare Pages picks up the Astro project automatically; the only config needed in the dashboard is:

  • Build command: npm run build
  • Build output directory: dist
  • Node version: 20 (or newer)

wrangler.toml declares the same so wrangler pages deploy works locally or from CI.

Static asset behaviour and redirects are controlled by:

To deploy from your laptop (one-off):

npm run build
npx wrangler pages deploy dist --project-name stalwart-website

Repository layout

.
├── astro.config.mjs        # Astro + Starlight integration config
├── src/
│   ├── content.config.ts   # Astro content collection schemas
│   ├── content/
│   │   ├── docs/
│   │   │   ├── docs/       # current docs   -> /docs/...
│   │   │   ├── docs/0.15/  # archived 0.15  -> /docs/0.15/...
│   │   │   └── blog/       # blog posts     -> /blog/...
│   │   ├── pages/          # marketing pages (YAML)
│   │   └── legal/          # long-form legal pages (Markdown)
│   ├── components/         # Astro components shared by marketing + docs
│   │   ├── Header.astro            # marketing nav
│   │   ├── Footer.astro            # marketing footer
│   │   ├── StarlightHeader.astro   # Starlight Header override -> Header
│   │   ├── StarlightFooter.astro   # Starlight Footer override -> Footer
│   │   └── VersionPicker.astro     # docs version dropdown
│   ├── layouts/            # marketing layouts (Base, LongForm)
│   ├── pages/              # marketing dynamic routes
│   └── styles/             # global tokens and Starlight overrides
├── public/                 # static assets copied as-is to dist/
└── scripts/                # one-off migration scripts (kept for reference)

Things to know

  • The links-validator plugin runs at the end of npm run build and fails the build on broken internal links. Pre-existing broken links in /docs/0.15/** are excluded (see astro.config.mjs); fix-forward only.
  • Mermaid diagrams (```mermaid) are converted to client-rendered SVG via the mermaid npm package; the script is bundled into Starlight pages only.
  • The .old/ directory is the archived Docusaurus tree, kept out of git via .gitignore until you choose to delete it.