Keep your help center in git
Your help articles can live in your repository as Markdown, reviewed in pull requests like code. On every merge, CI pushes them to your help center: new pages are created, changed pages get a new revision and are published, and everything else is left alone. Translations, search, feedback and the public site work as they do for articles written in Mocco. Mocco's own guides are published this way.
1. Lay out the folder
Put each section's pages in a folder, with their images in images/ beside them:
docs/help/
help.json
glossary.csv (optional)
start/
overview.md
install.md
images/
home.png
billing/
plans.mdEach page starts with frontmatter that has a title. The page's own # Title line, if it has one, is dropped, because the site shows the title as the page heading.
---
title: Install the app
---
# Install the app
Download it from the [overview](./overview.md#download).
Links between pages are ./page.md or ../folder/page.md, with an optional #anchor. On the site they lead to that article in the reader's language. Images are ./images/<name> (PNG, JPEG, WebP or GIF, up to 10 MB). Any other relative link fails the push, so a typo is caught before it reaches readers.
2. Write the manifest
help.json says where each folder appears and in what order:
{
"collections": [
{
"slug": "guides",
"title": "Guides",
"sections": [
{ "folder": "start", "title": "Getting started", "pages": ["overview", "install"] },
{ "folder": "billing", "title": "Billing", "pages": ["plans"] }
]
}
]
}A page the manifest doesn't list follows the listed ones alphabetically. A folder it doesn't list fails the push.
3. Create a key
On the project's API keys page, create a secret key with only the help:write scope. Store it as a CI secret, for example MOCCO_API_KEY. The project needs its help center set up first.
4. Push from CI
name: Help center
on:
push:
branches: [main]
paths: ['docs/help/**']
jobs:
push:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- run: npx @mocco/cli help push docs/help --glossary docs/help/glossary.csv --prune
env:
MOCCO_API_KEY: ${{ secrets.MOCCO_API_KEY }}Pin the action and the CLI version you use. The command prints what it did:
12 page(s), 30 image(s), 8 glossary term(s).
Images: 2 uploaded, 28 already stored.
Glossary: 0 added, 1 changed, 7 unchanged.
Articles: 0 created, 3 updated, 9 unchanged; 3 published, 0 unpublished.Images are offered by their checksum first, so a push only uploads new ones.
--dry-runchecks every page, link and image and sends nothing. It needs no key, so run it on pull requests.--pruneunpublishes pages pushed before that are no longer in the folder. Their history and translations stay, and a page that comes back is published again. Articles written in Mocco are never touched.--no-publishleaves new and changed pages as drafts, to publish from Mocco.--glossaryadds or updates glossary terms from a CSV in the same format as Import CSV on the Glossary page. Terms the file doesn't have stay.
5. Translations
If the help center offers other languages, each published change is translated automatically. Only the paragraphs that changed are sent again. A translation someone reviewed in Mocco is never overwritten: the new machine text waits beside it as a proposal. See Publish a help center.
Each page's path in the folder (/start/install) is kept as an address on the site that redirects to the article. Renaming a page's file makes it a new article; with --prune the old one is unpublished.