---
title: Docs
description: The documentation site that ships with the starter kit, for you to write your own product docs in.
---

`apps/docs` is a documentation site for your own product. It ships empty, or
close to it. The pages inside it are placeholders. You replace them with your
own.

This is not the site you are reading now. This site documents the starter kit.
`apps/docs` is the site you give to your users.

It is built with [Blume](https://useblume.dev). Blume takes a folder of
Markdown files and turns it into a website.

## Running it

```bash
pnpm run dev:docs
```

The site opens on port 3002, at `http://localhost:3002`. Edit any file under
`apps/docs/content/` and save. The page reloads on its own.

## Writing a page

Every page is one file in `apps/docs/content/`. The path of the file becomes
the address of the page. So `content/guides/configuration.mdx` is served at
`/guides/configuration`.

Each file starts with frontmatter. Frontmatter is a small block at the top that
holds the title and the description.

```mdx
---
title: Quickstart
description: Install the project, run it, and make your first change.
sidebar:
  order: 1
---
```

After that block, you write normal Markdown. You can also use components that
Blume gives you. The pages that ship already use several of them:

- `<CardGroup>` and `<Card>`, for a grid of links
- `<Steps>` and `<Step>`, for steps in order
- `<Tabs>` and `<Tab>`, for one idea shown two ways
- `<FileTree>`, for a folder listing
- `:::note`, `:::tip` and `:::warning`, for a highlighted box

Copy the shape from a page that ships. That is the fastest way to start.

### Folders in the sidebar

A folder can carry a `meta.ts` file. It sets the name, the icon and the place
of that folder in the sidebar.

```ts
import { defineMeta } from "blume";

export default defineMeta({
  title: "Guides",
  icon: "book-open",
  order: 2,
});
```

## What ships, and what to replace

Four pages ship. All four are placeholders. Each one holds a `TODO` comment
that says so.

1. `content/index.mdx` — the front page, with a grid of four cards.
2. `content/quickstart.mdx` — how to install and run the project.
3. `content/guides/configuration.mdx` — where the settings live.
4. `content/concepts/architecture.mdx` — the apps and the packages.

Replace all four. They describe the starter kit, not your product. Keeping
them would ship our words to your users.

Change `blume.config.ts` next. It sets the name, the address and the look of
the site:

```ts
const SITE_NAME = "zap.ts";
const SITE_URL = "https://docs.zap-ts.zapstudio.dev";
```

The same file sets the color of the site, `#f2b41f`, and the two tabs at the
top: `Docs` and `API`.

## The API reference

The site has a second tab, at `/api`. It is not written by hand. It is built
from `apps/docs/openapi.json`, a file that lists every route of the API.

You do not edit that file. The [API](/apps/api) app writes it:

```bash
pnpm run openapi:generate
```

Run that after you add or change a route. The reference then matches your API.

## Checking your pages

Three scripts check the site. Run them before you deploy.

```bash
pnpm run docs:validate
pnpm run docs:audit
pnpm run docs:doctor
```

`validate` checks that your pages are well formed. `audit` and `doctor` look
for problems in the site as a whole. They are also useful when a page builds
but does not look right.

## Deploying

```bash
pnpm run deploy:docs:cloudflare
pnpm run deploy:docs:vercel
```

There is no `deploy` on its own: the host is always part of the name, so a
deploy never goes somewhere you did not name.

The site is static, so both hosts serve the same built folder. On Cloudflare,
`wrangler.jsonc` points at it. On Vercel, `vercel.json` does: it builds with
`pnpm run build` and serves `dist`. There is nothing else to set on either
host, because a static site has no environment variable and no server.

The site is static. Blume builds plain HTML files into `apps/docs/dist/`, and
`wrangler.jsonc` serves that folder from Cloudflare. Static means there is no
server to run and no environment variable to set.

The build also writes files for AI tools and for search engines: `llms.txt`,
`sitemap.xml` and `robots.txt`. Those come from the `ai` and `seo` settings in
`blume.config.ts`.

:::note
Change `SITE_URL` in `blume.config.ts` to your own address before the first
deploy. The sitemap and the link previews use it.
:::

## Related

- [API](/apps/api) — the app that writes `openapi.json`
- [Marketing](/apps/marketing) — the other public site in the workspace
- [Web](/apps/web) — the product your users sign in to
