This file provides guidance for AI coding agents working with the Velopack documentation repository.
This repository contains the official documentation website for Velopack, an installer and auto-update framework for cross-platform desktop applications. The site is built using Docusaurus 3, a modern static site generator.
Live Site: https://docs.velopack.io/
velopack.docs/
├── docs/ # Main documentation content (MDX files)
│ ├── index.mdx # Landing page
│ ├── getting-started/ # Quick-start guides for different languages
│ ├── integrating/ # SDK integration guides
│ ├── packaging/ # Building releases with vpk
│ ├── distributing/ # Deployment guides
│ ├── migrating/ # Migration guides from other frameworks
│ ├── reference/ # API reference (auto-generated)
│ └── troubleshooting/ # FAQ and debugging guides
├── blog/ # Blog posts
├── src/ # Custom React components and CSS
│ ├── components/ # Reusable React components
│ ├── css/ # Custom stylesheets
│ └── theme/ # Docusaurus theme customizations
├── static/ # Static assets (images, logos, favicons)
├── generator/ # C# project for generating API reference docs
├── scripts/ # Build and deployment scripts
├── docusaurus.config.ts # Main Docusaurus configuration
├── sidebars.ts # Sidebar navigation structure
└── package.json # Node.js dependencies and scripts
- Framework: Docusaurus 3.8.1
- Runtime: Node.js 18+
- Language: TypeScript/JavaScript (site), MDX (documentation)
- Package Manager: npm or yarn
- Reference Generator: C# (.NET) for auto-generating API documentation
# Install dependencies
npm install
# Start development server (http://localhost:3000)
npm run start
# Build for production
npm run build
# Serve production build locally
npm run servenpm run start- Start Docusaurus dev server with hot reloadnpm run build- Build static site tobuild/directorynpm run serve- Serve production build locallynpm run clear- Clear Docusaurus cachenpm run typecheck- Run TypeScript type checking
The repository includes preconfigured VS Code tasks:
- Start Docusaurus Dev Server - Install dependencies and start dev server
- Install dependencies - Run npm install
Documentation is written in MDX (Markdown with JSX support), allowing you to:
- Use standard Markdown syntax
- Import and use React components
- Add interactive examples and demos
- Tutorials/Guides: Place in appropriate subdirectory under
docs/ - Blog Posts: Add to
blog/with YYYY-MM-DD format or subdirectories - API Reference: Auto-generated; don't edit directly (see Reference Generation below)
Add metadata to docs using frontmatter:
---
title: Page Title
sidebar_label: Short Label
sidebar_position: 1
disable_comments: true
---The site includes custom React components in src/components/. Notable examples:
<FancyStep>- Styled step-by-step instructions- Standard Docusaurus components like
<DocCardList>
API reference documentation is auto-generated from source code in the main Velopack repository.
- Location:
generator/directory - Language: C# (.NET)
- Purpose: Extracts API documentation and generates MDX files
The following reference docs are auto-generated:
- C# API Reference:
docs/reference/cs/ - CLI Reference:
docs/reference/cli/ - C++ Reference:
docs/reference/cpp/ - JavaScript Reference:
docs/reference/js/ - Python API Reference:
docs/reference/py/
cd generator
dotnet runThis updates all auto-generated reference documentation.
Main configuration including:
- Site metadata (title, tagline, URL)
- Theme configuration (navbar, footer, color modes)
- Plugins (search, redirects, analytics)
- Deployment settings
Defines the documentation sidebar navigation structure. Docusaurus supports:
- Auto-generated sidebars from directory structure
- Manual sidebar configuration
- Category grouping and custom ordering
- Create MDX file in appropriate
docs/subdirectory - Add frontmatter with title and metadata
- Update
sidebars.tsif manual ordering is needed - Test locally with
npm run start
- Locate the MDX file in
docs/directory - Edit content (preserve frontmatter)
- Verify links and references are valid
- Check for broken Markdown links (enforced by
onBrokenMarkdownLinks: 'throw')
- Create directory in
blog/with format:YYYY-MM-DD-slug/ - Add
index.mdorindex.mdxwith frontmatter - Include author information in
blog/authors.yml
- Edit
docusaurus.config.tsfor site-wide settings - Edit
sidebars.tsfor navigation structure - Rebuild site to see changes
- Custom components go in
src/components/ - Import in MDX files:
import Component from '@site/src/components/Component' - Theme overrides go in
src/theme/
Velopack supports multiple programming languages. When adding documentation:
| Language | Status | Quick-Start Path | Reference Path |
|---|---|---|---|
| C# | ✅ Ready | docs/getting-started/csharp.mdx |
docs/reference/cs/ |
| Rust | ✅ Ready | docs/getting-started/rust.mdx |
- |
| JavaScript | ✅ Ready | docs/getting-started/javascript.mdx |
docs/reference/js/ |
| C++ | ✅ Ready | docs/getting-started/cpp.mdx |
docs/reference/cpp/ |
| Python | ✅ Ready | docs/getting-started/python.mdx |
docs/reference/py/ |
The docs are translated into other languages (Spanish first) and the translations are written and maintained by AI, not by hand. The pipeline keeps them in sync as the English docs evolve.
Never hand-edit anything under i18n/. Edit the English source in docs/ (or the
site UI), and let the pipeline regenerate the localized content. Manual edits to
i18n/ will be overwritten the next time the corresponding English source changes.
- ✅ The 44 guide pages under
docs/(everything exceptdocs/reference/**) — fully AI-translated by the pipeline below. - ✅ Top nav + sidebar category labels — also AI-maintained by the pipeline (see
"Localizing nav & sidebar"). They re-translate automatically when you change a label in
docusaurus.config.ts/sidebars.ts. - ❌ Generic theme strings — search box, buttons, pagination, etc. (
code.json) — not in scope. Docusaurus ships its own bundled translations for most of them; anything it doesn't cover falls back to English. We deliberately don't own these (owning them means maintaining strings that aren't ours and overriding Docusaurus on every upgrade). - ❌ The auto-generated API reference (
docs/reference/**) — ~569 files, regenerated daily. Docusaurus automatically falls back to the English page when a localized doc is missing, so these stay English by design. - ❌ The blog — stays English.
scripts/translate.config.json— declareslocales, the docs source globs (docs/**minusreference/**), theuiJSON files (nav/sidebar) with their prune/keep rules, andcleanupAfter(transient files to delete post-run).scripts/translate.mjs— dependency-free Node 18+ script (built-infetch, no new npm packages). It hashes each English source and compares againsti18n/translation-manifest.json; only changed/missing pages are re-translated via the Anthropic Messages API and written toi18n/<locale>/docusaurus-plugin-content-docs/current/<relPath>.- Env:
ANTHROPIC_API_KEY(required),TRANSLATE_MODEL(optional, defaultclaude-sonnet-4-6). - Flags:
--locale <id>,--force(ignore the manifest),--dry-run.
- Env:
.github/workflows/translate.yml— on push tomastertouchingdocs/**,sidebars.ts,docusaurus.config.ts, or the translate script/config (or manual dispatch):npm ci→npm run i18n:scaffold→npm run translate→ commit anyi18n/**changes asgithub-actions[bot]→ dispatchdeploy.yml. The commit only touchesi18n/**, which is not in the workflow's trigger paths, so it never re-triggers itself (mirrors thegenerate.ymlpattern).- Requires the
ANTHROPIC_API_KEYrepo secret (set in GitHub repo settings).
- Requires the
npm run translate— run the translation engine locally (needsANTHROPIC_API_KEY).npm run i18n:scaffold—docusaurus write-translationsfor the locale anden, producing the English baseline the UI step diffs against. Run this beforetranslateif you want nav/sidebar labels (re)translated locally; the markdown pipeline doesn't need it.
Building a non-default locale (e.g. es) makes Docusaurus generate sidebar translation
keys, and it throws on duplicate keys. The auto-generated C# reference repeats category
labels (Methods, Properties, etc.) across every type, so each _category_.yml must
carry a unique key:. This is emitted by the generator (generator/CSharpReference.cs)
and present in the committed tree — don't remove it, or npm run build will fail for es.
Reference images with absolute site paths (/images/foo.png, served from
static/images/) so they resolve from both docs/ and the relocated i18n/ copies. Avoid
relative (../../../static/...) or co-located (foo.png) image paths — they break in the
translated build. Likewise, if a heading is the target of an in-page #anchor link, give it
an explicit stable id (## Heading {#stable-id}) so the link survives translation of the
heading text.
The top-nav and sidebar-category labels are translated by the same pipeline as the
guides, via a small ui section in scripts/translate.config.json. Two files per locale:
i18n/<locale>/docusaurus-theme-classic/navbar.json— top-nav item labels (Guides, Reference, Blog) + logo alt text.i18n/<locale>/docusaurus-plugin-content-docs/current.json— sidebar category labels (Getting Started, Integrating, …).dropKeyPrefixesstrips the auto-generated reference sub-categories (Methods, Properties, per-class — they stay English and would churn daily), the Sample-Apps links (tech-stack names), andversion.label;keepKeysretains the single stable top-levelReferencelabel.
How it stays in sync (in translate.mjs → translateUi):
- CI runs
npm run i18n:scaffoldfirst (write-translationsfor the locale and foren), producing the English baseline. - A key is (re)translated only when its message still equals the English baseline, so existing translations never drift and new/renamed labels are picked up automatically.
- Re-translation is gated on a hash of the pruned English baseline (stored in the
manifest's
__uisection), so it only fires when a label actually changes indocusaurus.config.ts/sidebars.ts— hence those two files are intranslate.yml's trigger paths. Proper nouns (Blog, Flow, C#, Python…) correctly stay as-is. cleanupAfterdeletes the transienti18n/enbaseline and the scaffold byproducts we don't own (code.json, blog options) so they're never committed.
Per-page sidebar entries (C#, FAQ, …) localize automatically via each doc's translated
sidebar_label frontmatter — no JSON needed.
code.json is intentionally NOT committed. It's generic theme chrome (search box,
buttons, pagination) that Docusaurus already translates via its bundled locale data;
owning it would mean overriding Docusaurus on every upgrade. Anything it doesn't cover
falls back to English.
- Add the locale to
docusaurus.config.ts:i18n.locales,i18n.localeConfigs(label +htmlLang), and the search theme'slanguage: [...]array. - Add the locale to
scripts/translate.config.json(localesandlocaleLabels). - Run
npm run i18n:scaffold && npm run translate(or just push tomasterand let CI do it). This translates the guide pages and the nav/sidebar labels for the new locale. - Verify with
npm run build(builds all locales,onBrokenLinks: 'throw'applies to every locale).
Translate prose, headings, table cell text, alt text, and link text only. Never touch:
frontmatter keys (only title/sidebar_label/description values are translated), code
fences & inline code, JSX tags/attributes/props, import lines, URLs/paths, HTML tags,
anchor ids, or Velopack product/CLI terms (vpk, Velopack, Squirrel, ClickOnce,
command names).
See i18n/README.md for a shorter summary.
- Internal docs: Use relative paths:
[text](./page.mdx)or[text](../category/page.mdx) - External: Use full URLs:
[text](https://example.com) - Broken links: Will cause build to fail (enforced by config)
Use language-specific syntax highlighting:
```csharp
// C# code example
```
```bash
# Shell commands
```Old URLs are redirected in docusaurus.config.ts:
redirects: [
{ from: '/old-path', to: '/new-path' },
]Add new redirects when moving/renaming pages.
- Build succeeds:
npm run build(catches broken links, invalid config) - TypeScript checks:
npm run typecheck - Visual review: Test on dev server (
npm run start) - Search works: Verify search index includes new content
The configuration includes strict checks:
onBrokenLinks: 'throw'- Broken internal links fail the buildonBrokenMarkdownLinks: 'throw'- Invalid Markdown links fail the build
The site is deployed automatically via CI/CD. Deployment configuration is in docusaurus.config.ts:
url: 'https://docs.velopack.io/',
baseUrl: '/',
organizationName: 'velopack',
projectName: 'velopack.docs',Search is powered by @easyops-cn/docusaurus-search-local:
- Automatically indexes all documentation
- Blog posts are excluded from indexing
- Reference documentation is excluded via regex pattern
- Search index is built during
npm run build
- Documentation edits have "Edit this page" links pointing to GitHub
- Reference pages cannot be edited (auto-generated)
- Follow existing structure and conventions
- Test locally before committing
- Ensure builds pass without errors
- Docusaurus Docs: https://docusaurus.io/docs
- Velopack Main Repo: https://github.com/velopack/velopack
- Discord Community: https://discord.gg/CjrCrNzd3F
- Live Documentation: https://docs.velopack.io/
- Do not edit auto-generated reference docs - They're regenerated from source code
- Respect the MDX format - Maintain frontmatter and JSX syntax
- Test builds locally - Strict link checking will fail CI if broken
- Follow existing patterns - Match the style and structure of existing docs
- Update sidebars.ts - If adding new sections or changing navigation
- Use TypeScript - Configuration files use TypeScript for type safety
- Check package.json - For correct commands and dependencies
- Preserve React components - Don't convert JSX to plain Markdown if components are used
- Build fails on broken links: Check
npm run buildoutput for specific broken links - Search not working: Rebuild with
npm run buildto regenerate search index - Dev server issues: Clear cache with
npm run clearand restart - Missing dependencies: Run
npm installto ensure all packages are installed - TypeScript errors: Run
npm run typecheckto see type issues
- Check existing documentation structure for examples
- Review Docusaurus documentation for framework-specific questions
- Join Velopack Discord for project-specific questions