# 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.md
```

Each 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.

```markdown
---
title: Install the app
---

# Install the app

Download it from the [overview](./overview.md#download).

![The home screen after installing](./images/home.png)
```

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:

```json
{
  "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

```yaml
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-run` checks every page, link and image and sends nothing. It needs no key, so run it on pull requests.
- `--prune` unpublishes 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-publish` leaves new and changed pages as drafts, to publish from Mocco.
- `--glossary` adds 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](./help-center.md).

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.
