Public-facing documentation site for privacytracker, built with Mintlify.
Production is a Cloudflare Worker serving the static export as assets
(wrangler.jsonc). just deploy builds and publishes it.
Hostname: docs.privacytracker.privacykey.org (DNS not configured yet)
The site is organised around two distinct readers, with a third tab for the API:
- Self-Host tab — the default. For people installing and running privacytracker on their own machine via the signed desktop app, Homebrew cask, or Docker. No source checkout assumed.
- Develop tab — for people building from source, contributing, integrating against the API, or understanding the internals (architecture, feature flags, translations, the docs site itself).
- API Reference tab — interactive endpoint pages auto-generated from
api-reference/openapi.yaml, plus a hand-written overview covering authentication, conventions, and rate-limiting.
Internal release engineering — code signing, notarization, the GitHub Actions that publish notarized builds — is intentionally not in this site. That stays in the project's .github/wiki/ so it doesn't crowd out user-facing docs.
# Check docs.json navigation, internal links, anchors, assets, and OpenAPI wiring
npm run check
# Run the live preview from the docs root (where docs.json lives)
npm run devOpen http://localhost:3000. The preview hot-reloads as you edit MDX files.
npm run check uses only Node built-ins, so it works without installing the Mintlify CLI first. npm run dev launches Mintlify through npx.
docs-privacytracker/
├── docs.json Mintlify site config (theme, navigation, OpenAPI wiring)
├── package.json Local docs scripts (check, dev, sync-changelog, linkcheck)
├── README.md (this file)
├── CONTRIBUTING.md How to propose and structure doc changes
├── LICENSE Apache-2.0
├── .gitignore
├── llms.txt AI-readable index of every page (generated, committed)
├── llms-full.txt The whole site as one Markdown file (generated, committed)
├── scripts/
│ ├── check-docs.mjs Local smoke check for navigation, internal links, anchors, assets
│ ├── sync-changelog.mjs Pulls the main repo's CHANGELOG.md into changelog.mdx
│ └── build-llms.mjs Generates llms.txt, llms-full.txt, and per-page Markdown
│
├── introduction.mdx Self-Host · Get Started: landing page
├── alternatives.mdx Self-Host · Get Started: how privacytracker compares
├── quickstart.mdx Self-Host · Get Started: 5-minute install + first import
├── installation.mdx Self-Host · Get Started: desktop / Homebrew / Docker
├── configuration.mdx Self-Host · Get Started: settings, AI providers, env vars
├── cookbook.mdx Self-Host · Recipes: task-oriented walkthroughs
├── performance-and-sizing.mdx Self-Host · Operate: resource use and scaling
├── backup-and-restore.mdx Self-Host · Operate: backup, restore, migrate between install paths
├── security.mdx Self-Host · Operate: data posture, audit bundles, threat model
├── hardening.mdx Self-Host · Operate: locking down a self-hosted deployment
├── upgrading.mdx Self-Host · Operate: upgrading across versions
├── troubleshooting.mdx Self-Host · Operate: common issues with diagnostics + fixes
├── faq.mdx Self-Host · Help: common questions
├── glossary.mdx Self-Host · Help: domain terms used across the app
├── changelog.mdx Self-Host · Help: mirror of main repo's CHANGELOG.md
├── about-these-docs.mdx Self-Host · Help: how these docs are written and maintained
│
├── develop/
│ ├── overview.mdx Develop: who this section is for
│ ├── build-from-source.mdx Develop: clone + npm install + run / test / build
│ ├── scripts.mdx Develop: the repo's helper scripts
│ ├── contributing.mdx Develop: PR workflow, what makes a good change
│ ├── architecture.mdx Develop: codebase + data flow + Mermaid diagrams
│ ├── feature-flags.mdx Develop: focus model + per-flag override
│ ├── tauri.mdx Develop: the desktop shell, packaging, and updater
│ ├── translations.mdx Develop: Crowdin + next-intl workflow (the app)
│ ├── translating-the-docs.mdx Develop: how to add a language to this docs site
│ └── versioning.mdx Develop: how this docs site is versioned
│
├── api-reference/
│ ├── introduction.mdx API: hand-written overview (auth, CSRF, conventions)
│ └── openapi.yaml OpenAPI 3.1 spec — Mintlify auto-generates one page per operation
│
├── images/ Screenshots, diagrams (favicon.svg lives here)
│ ├── SCREENSHOTS.md Capture guide: what shots are needed and where they go
│ ├── favicon.svg
│ └── screenshot-placeholder.svg Fallback placeholder for future new pages
├── logo/ light.svg + dark.svg used by docs.json
├── essentials/ Reserved (empty for now)
├── snippets/ Reusable MDX fragments (empty for now)
│
└── .github/workflows/
├── linkcheck.yml lychee link-check on every PR + weekly cron
└── sync-changelog.yml Syncs changelog.mdx from the main repo's CHANGELOG.md
- Pages are MDX (Markdown + JSX). Mintlify components like
<Card>,<Steps>,<Tabs>,<Accordion>,<CodeGroup>, and<Frame>are available out of the box — see Mintlify components. - After adding a new page, register it under
navigation.tabs[*].groups[*].pagesindocs.json. Pages not listed there are reachable by URL but absent from the sidebar. - Internal links use the page slug without
.mdx(e.g./develop/architecture). - Run
npm run checkbefore opening a PR; it catches missing sidebar pages, broken internal links, missing anchors, missing assets, and a missing / malformed OpenAPI file. - Run
npm run llmsafter editing a page and commit the regeneratedllms.txtandllms-full.txt;npm run checkfails when they are out of date. - Keep self-hoster pages free of
lib/*filenames and code-internal jargon. If a page assumes a source checkout, it belongs underdevelop/. - Architecture diagrams use Mintlify's native Mermaid support — fenced ```mermaid blocks render as SVG.
- The API Reference's per-endpoint pages are auto-generated from
api-reference/openapi.yaml. Edit the spec, not the pages — they're regenerated on every build.
The site follows the llms.txt convention. llms.txt at the repository root indexes every page with its one-line description, and llms-full.txt is the whole site as one Markdown file, including a method-by-method table of the API. Both are committed, so they read fine straight from GitHub, and both are served from the site root. The build also writes every page as plain Markdown beside its HTML, so appending .md to any page URL returns the Markdown, and copies api-reference/openapi.yaml so the raw spec is served too.
scripts/build-llms.mjs generates all of it from docs.json, each page's frontmatter, and the OpenAPI file, using only Node built-ins. Run npm run llms after editing a page and commit the result; npm run check fails when the committed copies are out of date, and sync-changelog.yml regenerates them itself.
The linkcheck.yml workflow runs the local smoke check first, then lychee on every PR that touches MDX/MD/docs.json/package.json/scripts/**/openapi.yaml, and on a weekly cron to catch external-link rot. Failed scheduled runs auto-open an issue. Cache key: cache-lychee-<sha>; first run is slow, subsequent runs hit the cache.
To run locally:
# Once: install lychee
brew install lychee
# Then, from the docs root:
npm run check
npm run linkcheckThe docs site is English-only today; the framework is in place to add others. See Translating the docs (or develop/translating-the-docs.mdx if you're previewing locally) for the step-by-step.
The required screenshot set lives in images/. The capture guide is at images/SCREENSHOTS.md — it lists every filename, where to capture it from in the running app, and which doc pages reference it.
Documentation content is licensed under Apache-2.0, matching the main privacytracker project.