---
title: Configure docs sources
description: "Choose where Leadtype reads MDX from: one local docs folder,
  multiple mounted folders, or remote git collections pinned to a branch, tag,
  or commit."
---
Leadtype can read from one local docs folder, multiple local folders, or remote
git repositories. For a small single-repo project, start with one local folder.
For hosted product docs where the docs UI is separate from the package/source
repo, start with a pinned remote collection and inherit the source repo's
source-owned docs config.

## Pick the right source shape

|Shape|Use when|Configure with|
|--|--|--|
|One docs folder|Docs live beside the app or package that publishes them.|`docs/docs.config.ts` + `leadtype generate --src .`|
|One docs folder with mounted subtrees|One source tree owns all content, but a subtree needs a top-level URL such as `/changelog`.|`docs/docs.config.ts` `mounts`|
|Multiple local folders|Related content lives in sibling folders, such as `docs/` and `changelog/`.|Repeated `--docs-dir` flags|
|Pinned remote collection|Recommended hosted-site shape. A docs UI repo renders a reviewed package/source `ref` and inherits source-owned navigation/schema/flatteners/mounts.|Docs UI `leadtype.config.ts` with `sourceConfig: true`|
|Collections|Sources need separate prefixes, filters, schemas, or local/remote acquisition.|Project-level `leadtype.config.ts`|

Use one docs folder when ownership is simple. Use pinned remote collections when
the docs site is a hub for content owned by another repo, package, framework, or
release stream. Use `mounts` when the source is still one docs tree and only the
public URL differs.

## One local docs folder

Put MDX under `docs/` and product/nav metadata in `docs/docs.config.ts`:

```ts title="docs/docs.config.ts"
import { defineDocsConfig } from "leadtype";

export default defineDocsConfig({
  product: {
    name: "My product",
    tagline: "Developer tools for modern apps.",
  },
  llms: {
    sections: [
      {
        type: "links",
        heading: "Best Starting Points",
        links: [
          {
            urlPath: "/docs",
            title: "Overview",
            description: "Start page for the docs site.",
          },
          {
            urlPath: "/docs/quickstart",
            title: "Quickstart",
            description: "First steps for setting up My product.",
          },
        ],
      },
    ],
  },
  navigation: [
    "index",
    "quickstart",
    { title: "Guides", pages: [{ include: "guides/*" }] },
    { title: "Reference", pages: [{ include: "reference/*" }] },
  ],
});
```

Then generate:

```bash
npx leadtype generate --src . --out public --base-url https://example.com
```

This reads `./docs`, writes website artifacts to `public`, and exposes pages under `/docs`. Top-level string entries become root pages instead of groups. Use `index` for `docs/index.mdx`; Leadtype strips `index` from generated URLs so that page still resolves to `/docs`.

### Mount a subtree at a top-level URL

Use `mounts` when a subtree is part of the same docs source but should not live
under `/docs` publicly. A common example is a changelog kept at
`docs/changelog/*.mdx` by the same repo and config as the rest of the docs:

```ts title="docs/docs.config.ts"
import { defineDocsConfig } from "leadtype";

export default defineDocsConfig({
  product: {
    name: "My product",
    tagline: "Developer tools for modern apps.",
  },
  navigation: [
    "index",
    "quickstart",
    {
      title: "Changelog",
      base: "changelog",
      optional: true,
      pages: ["v1"],
    },
  ],
  mounts: [{ pathPrefix: "changelog", urlPrefix: "/changelog" }],
});
```

With that mount, `docs/changelog/v1.mdx` still generates an internal copy at
`public/docs/changelog/v1.md` for search and runtime helpers, but canonical
URLs become `/changelog/v1` and `/changelog/v1.md` in `llms.txt`, sitemap data,
search metadata, and `agent-readability.json`.

Prefer this over a second collection when the changelog shares the same source
repo, frontmatter schema, navigation ownership, and release process as the docs.
Use a collection only when the changelog is a separate source or needs separate
filters, schema, ownership, or remote acquisition.

## Multiple local folders

Repeat `--docs-dir` when a single source repo keeps agent-readable content outside the main docs folder:

```bash
npx leadtype generate \
  --src . \
  --docs-dir docs \
  --docs-dir changelog \
  --out public \
  --base-url https://example.com
```

The first folder becomes the generated docs root. Additional folders are nested under their folder name, so `changelog/v1.mdx` becomes `public/docs/changelog/v1.md` and `/docs/changelog/v1`.

Mount a folder at its own public URL prefix when it should not appear under `/docs`:

```bash
npx leadtype generate \
  --src . \
  --docs-dir docs \
  --docs-dir changelog=/changelog \
  --out public \
  --base-url https://example.com
```

Leadtype still keeps an internal generated copy for search and agent helpers, but canonical links, sitemap entries, and agent metadata point to `/changelog/v1`.

## Collections

Use collections when each source needs explicit ownership. Collections live in a project-level `leadtype.config.ts` at the directory passed to `--src`.

```ts title="leadtype.config.ts"
import { defineCollection, defineDocsConfig } from "leadtype";

export default defineDocsConfig({
  product: {
    name: "My product",
    tagline: "Developer tools for modern apps.",
  },
  collections: {
    docs: defineCollection({
      dir: "./docs",
      prefix: "/docs",
      navigation: ["index", "quickstart"],
    }),
    changelog: defineCollection({
      dir: "./changelog",
      prefix: "/changelog",
      include: ["*.mdx"],
    }),
  },
});
```

Run the same site-mode generate command:

```bash
npx leadtype generate --src . --out public --base-url https://example.com
```

When `leadtype.config.ts` defines `collections`, the collection map fully describes the sources. Do not combine collections with `--docs-dir`.

## Remote git sources

Set `repository` to make a collection remote. Pin `ref` to the version you want: a branch for moving docs, a tag for release docs, or a commit SHA for fully reproducible output.

For the split-repo docs UI shape, add `sourceConfig: true`. After sync,
Leadtype loads `docs.config.{ts,js,mjs,cjs}` from the remote collection `dir`
and inherits MDX-owned fields (`navigation`, `groups`, `frontmatterSchema`,
`flatteners`, and `mounts`) into the collection.

Keep this ownership split clear:

* Source repo: MDX, navigation/sidebar order, fallback groups, frontmatter schema,
  source-specific flatteners, and same-tree mounts such as
  `docs/changelog` -> `/changelog`.
* Docs UI repo: source `repository`/`ref`, product identity as rendered by the
  site, organization, agent policy, app shell, output paths, and deployment.

```ts title="leadtype.config.ts"
import { defineCollection, defineDocsConfig } from "leadtype";

const sdkDocs = {
  repository: "https://github.com/acme/sdk",
  ref: "v2.4.0",
  cacheDir: ".docs-src/sdk",
} as const;

export default defineDocsConfig({
  product: {
    name: "Acme",
    tagline: "Docs for Acme SDKs and platform APIs.",
  },
  collections: {
    platform: defineCollection({
      dir: "./docs",
      prefix: "/docs",
    }),
    sdk: defineCollection({
      ...sdkDocs,
      dir: "docs",
      prefix: "/docs/sdk",
      sourceConfig: true,
      include: ["quickstart.mdx", "guides/**", "reference/**"],
      exclude: ["**/internal/**"],
    }),
  },
});
```

If the source repo's `docs/docs.config.ts` declares
`mounts: [{ pathPrefix: "changelog", urlPrefix: "/changelog" }]`, the docs UI
repo inherits that mapping through `sourceConfig: true`. A remote page at
`docs/changelog/v1.mdx` is generated with canonical URLs `/changelog/v1` and
`/changelog/v1.md`, not `/docs/changelog/v1`.

The docs UI repo can also declare `mounts` directly on the collection when it
needs to override an older pinned source ref that does not yet include the
source-owned mount:

```ts title="leadtype.config.ts"
docs: defineCollection({
  ...sdkDocs,
  dir: "docs",
  prefix: "/docs",
  sourceConfig: true,
  mounts: [{ pathPrefix: "changelog", urlPrefix: "/changelog" }],
});
```

Sync the remote source before generating:

```bash
npx leadtype sync --src .
npx leadtype generate --src . --out public --base-url https://example.com
```

Or clone missing caches and generate in one command:

```bash
npx leadtype generate --src . --out public --base-url https://example.com --sync
```

## Pinning strategy

|`ref` value|Best for|Sync behavior|
|--|--|--|
|Branch, such as `main`|Preview docs that should move with the source repo.|Shallow clone or fetch that branch. Use `--refresh` when you want latest commits.|
|Tag, such as `v2.4.0`|Release docs that should match a published version.|Clone that tag. Update the config to move releases.|
|Commit SHA|Fully reproducible builds and audits.|Checkout that exact commit. Use a 7-40 character SHA.|

For CI, use tags or commit SHAs when the generated docs must be reproducible. Use branches for preview environments or docs hubs that intentionally track the latest upstream content.

## Sync modes

|Command|Network behavior|Use when|
|--|--|--|
|`leadtype sync`|Clones missing remote caches only.|Local setup and CI steps before generate.|
|`leadtype sync --refresh`|Re-fetches and fast-forwards existing caches.|You track a branch and want new upstream commits.|
|`leadtype generate`|Does not clone. Fails if a remote cache is missing or stale.|CI already ran `leadtype sync`.|
|`leadtype generate --sync`|Clones missing caches before generation.|You want one command for setup and generate.|
|`leadtype generate --offline`|Never touches the network.|Hermetic or air-gapped builds.|

Each synced repo gets a `.leadtype-sync.json` manifest in its cache directory. Leadtype reads that manifest during generate so stale or missing remote sources fail loudly instead of silently producing docs from the wrong revision.

## Package bundle filters

For npm package docs, use `--bundle` and filter to the docs that belong to that package:

```bash
npx leadtype generate \
  --bundle \
  --src . \
  --out packages/react \
  --include "frameworks/react/**" \
  --include "shared/**" \
  --exclude "**/internal/**"
```

Bundle mode writes `AGENTS.md` and `docs/*.md` into the package. See [Bundle docs into a package](/docs/package-docs/bundle) for the full publish flow.

## What to read next

* [Build a docs site](/docs/build/build-a-docs-site)
* [Generate static artifacts](/docs/build/generate-static-artifacts)
* [CLI reference](/docs/reference/cli)
