---
title: Create an internal knowledge base
description: Build a team knowledge base with Reed, put it behind your own access control, and keep it from decaying.
---

An internal knowledge base gives your team one place to find answers and one place to
record them. When knowledge is spread across chat threads, wikis, shared drives and
people's heads, a search returns the wrong answer or none at all. A knowledge base fixes
that by making one source the source of truth.

This guide covers building one with Reed: migrating what you have, structuring it, keeping
it private, and making sure it is still right a year from now.

## Is Reed the right tool for this?

Be clear about the trade before you start. Reed is a compiler: it turns a directory of MDX
files and one `docs.json` into a static site. That shapes what a knowledge base on Reed is
like.

What you get:

- **Pages in git.** Every change is a commit, every edit is reviewable, and nothing is lost
  when someone overwrites a page.
- **Fast search with nothing to run.** Search is built into the site and runs in the
  reader's browser. There is no search server to operate.
- **A site that outlives the tool.** The output is static files you host anywhere.
- **Plain-text copies for AI tools.** Every build writes `llms.txt` and a markdown mirror of
  each page, so your team's own AI tooling can read the knowledge base without scraping it.
  See [llms.txt](/docs/derived/llms-txt).

What you do not get:

- **Access control.** Reed has no login, no SSO, no user groups and no per-page permissions.
  "Internal" is something you enforce in front of the site, not inside it. The next
  sections show how.
- **A web editor.** Contributors edit files in git. There is no in-browser editor from Reed.
- **An assistant or chat integration.** No question-answering widget on the page and no bot
  in your chat tool.
- **Usage reporting of its own.** Page views come from an analytics provider you configure.

If most of your contributors will never open a pull request, weigh that honestly. A
knowledge base nobody updates is worse than none. If your team already lives in git, the
trade is a good one.

## Prerequisites

- Reed installed and a project that builds. See the [Quickstart](/docs/quickstart).
- A git repository your contributors can reach.
- A place to host static files that you can put behind authentication: a Cloudflare Pages
  project with Cloudflare Access, a bucket behind your VPN, or an nginx server you control.

## Migrate existing content

If you are starting from scratch, skip to [designing the navigation](#design-the-navigation-structure).

### Audit what you have

Catalog your current knowledge base before you move it. The catalog sizes the migration,
shapes the new structure, exposes gaps, and gives you a checklist to confirm everything
arrived.

- **Number of articles.** Sets the effort estimate and lets you track completeness.
- **Topics.** Tells you what the navigation has to hold.
- **Current organization.** Shows whether the existing structure is worth keeping.
- **Content types.** Text, PDFs, videos and embeds each migrate differently.
- **Metadata.** Dates, authors and tags you need to preserve somewhere.
- **Audiences.** Who is allowed to read what. This decides how many sites you build, as
  covered below.

### Export your content

Most wiki and knowledge-base tools export in standard formats.

- **Markdown** is the simplest path, and the one to choose if it is offered. Reed pages are
  MDX, and most Markdown is valid MDX.
- **HTML** works when Markdown is not available. You will convert it before it becomes a
  page.
- **JSON or CSV** preserves structured metadata, such as owners and review dates, that you
  may want to carry into the new pages or into a separate ownership list.

Reed has no importer for wiki platforms. `reed import --from fern` is the only conversion
path it ships, so a migration from anything else is an export, a conversion and a cleanup.

## Design the navigation structure

Navigation decides how people find things. You can recreate your existing structure or use
the migration to fix it.

<Tip>
  Ask whether the current structure actually works. If people navigate your old wiki only
  through search, its hierarchy is not helping anyone, and you are free to redraw it.
</Tip>

On Reed the structure lives in the `navigation` field of `docs.json`, as tabs holding groups
holding pages:

```json
{
  "navigation": {
    "tabs": [
      {
        "label": "Handbook",
        "groups": [
          {
            "label": "Finance",
            "pages": [
              "finance",
              "finance/budgeting-process",
              "finance/expense-reports",
              "finance/cost-allocation"
            ]
          },
          {
            "label": "People",
            "pages": ["people", "people/onboarding", "people/benefits", "people/time-off"]
          },
          {
            "label": "Engineering",
            "pages": [
              "engineering",
              "engineering/dev-setup",
              "engineering/deployment",
              "engineering/code-standards"
            ]
          }
        ]
      }
    ]
  }
}
```

A tab holds groups, a group holds pages, and groups can nest up to five levels. Keep it
shallower than that. [How to structure documentation navigation](/docs/guides/navigation)
covers depth, naming and testing the structure with real readers.

## Keep it internal

Reed does nothing to restrict who can read the site. Everything in the build output is
public to anyone who can reach the URL. You make it internal by putting the whole output
behind an access layer you already trust:

- **An identity-aware proxy** such as Cloudflare Access in front of a Cloudflare Pages
  project, which checks your identity provider before serving any file.
- **A private network.** Serve the files from a host that is only reachable over your VPN
  or office network.
- **Web-server authentication**, such as nginx `auth_basic` or an auth module in front of
  the directory. This is the bluntest option and fine for a small team.

Protect the whole directory, not just the HTML pages. The build also contains `llms.txt`,
a `.md` mirror of every page, and the search index, and each of them carries your content.
A gate that covers only `*.html` leaks the rest.

### When different teams need different content

Reed has no groups and cannot hide a page from some readers and show it to others. If a
section must be restricted to one team, build it as a separate Reed project and put it
behind its own access policy, at its own URL or `base`. Two builds cost you a second
navigation and no search across both. Before you pay that, check whether the restriction
is real. Most knowledge-base content is fine for everyone inside the company.

## Migrate your content

Move the exported files into a layout that matches your navigation, convert what needs
converting, and fix the links.

### Organize the files

A page's id comes from its path under `content/`, and that id is what `navigation` lists.
`content/finance/expense-reports.mdx` is the page `finance/expense-reports`. A file named
`index.mdx` inside a folder takes the folder's id, so `content/finance/index.mdx` is the
page `finance` — a natural overview page for the section.

<Files>
  <File name="docs.json" />
  <Folder name="content" defaultOpen>
    <Folder name="finance" defaultOpen>
      <File name="index.mdx" comment="page id: finance" />
      <File name="budgeting-process.mdx" />
      <File name="expense-reports.mdx" />
      <File name="cost-allocation.mdx" />
    </Folder>
    <Folder name="people">
      <File name="index.mdx" />
      <File name="onboarding.mdx" />
      <File name="benefits.mdx" />
      <File name="time-off.mdx" />
    </Folder>
    <Folder name="engineering">
      <File name="index.mdx" />
      <File name="dev-setup.mdx" />
      <File name="deployment.mdx" />
      <File name="code-standards.mdx" />
    </Folder>
  </Folder>
</Files>

Every file must be listed in `navigation`. A page left out fails `reed check` with
`content-page-not-in-navigation`, so you find the stragglers before anyone else does.

### Add frontmatter to each page

Every page needs a `title` and a `description`. The title becomes the page heading, so do
not repeat it as a `#` heading in the body; start at `##`.

```mdx
---
title: Submit an expense report
description: How to file an expense report, attach receipts and track reimbursement.
---

## Before you start
```

See [Pages](/docs/authoring/pages) for the details.

### Fix internal links

Old wiki links will not survive the move. Rewrite them as root-relative paths built from the
page id. If your site sets a `base`, include it yourself: on a site mounted at `/handbook`,
a link to onboarding is written `[Onboarding](/handbook/people/onboarding)`. Reed does not
rewrite links, so a link missing the base compiles cleanly and 404s.
[How to link documentation pages effectively](/docs/guides/linking) covers the rule and how
to check links mechanically.

### Convert HTML and other formats

If you exported HTML, convert it to Markdown. Pandoc handles most of it from the command
line:

```sh
pandoc expense-reports.html -f html -t gfm -o content/finance/expense-reports.mdx
```

Then read every converted page. Conversions leave behind stray markup, broken tables and
headings at the wrong level, and some leftover HTML is not valid MDX. Convert in batches and
run `reed check` and `reed build` after each one, so a broken page is found while you still
remember where it came from.

### Decide what to do with PDFs and videos

- **Videos.** Reed has no video component. Host the video on a platform built for it, link
  to it, and put the essential information in the page text too. See
  [How to use images, screenshots and videos](/docs/guides/media).
- **PDFs.** Reed does not publish arbitrary files alongside your pages. Host PDFs somewhere
  your team can reach and link to them by absolute URL — or, better, convert the ones people
  actually read into pages, so they are searchable.
- **Images** go next to the page that uses them, referenced with a relative path. The media
  guide explains why.

## Enable team contributions

A knowledge base stays accurate only when the people who notice a mistake can fix it.
Reed's contribution model is git, so make git as easy as it can be.

- **Edit in the browser on your git host.** Most git hosts let anyone with access edit a
  file and open a pull request without installing anything. For a one-paragraph fix, that
  is the lowest-friction path.
- **Edit locally with a preview.** Contributors who make larger changes run `reed dev` for
  a live preview while they edit.
- **Review every change.** Pull requests give each change an author, a reviewer and a
  history. Run `reed check` on each one in CI so broken navigation never merges. See
  [Git workflows for documentation](/docs/guides/git-workflows).

### Capture knowledge from chat

Much of what a team knows is first written in a chat thread and never makes it any further.
Reed has no chat integration, so capture has to be a habit. When a thread settles a
technical decision, a fix or a process, whoever resolved it opens an issue or a pull
request with the answer while the context is fresh. An AI coding assistant working in the
docs repository can do the drafting if you paste in the thread. A person still reviews the
result before it merges.

## Establish maintenance workflows

Knowledge bases decay fast. Build the maintenance in from day one.

### Assign an owner to every section

An owner does not write every page. They review the section regularly, flag what is out of
date, approve new pages, and respond when someone reports an error. Writing owners into a
`CODEOWNERS` file makes your git host request their review automatically.

### Set review cycles

Content goes stale at different rates. A reasonable starting schedule:

- **Critical content**, such as security and incident procedures: every 30 days.
- **Standard content:** every 90 days.
- **Evergreen content:** once a year.

When reviewing, check that links still work, systems and processes have not changed,
examples are current, and nothing new belongs on the page. Git history tells you when each
page last changed. [How to maintain documentation over time](/docs/guides/maintenance)
shows how to surface stale pages from it.

### Write contribution guidelines

Make it easy for anyone to help. Cover:

- **Format:** the templates and structure pages should follow.
  [Content templates](/docs/guides/content-templates) is a starting point.
- **Process:** how to propose a change and open a pull request.
- **Review:** who reviews, and how quickly.
- **Scope:** what belongs in the knowledge base and what does not.

### Watch how it is used

Configure an [analytics provider](/docs/site/analytics) for page views. For an internal
site, a self-hosted Plausible, Umami or Matomo instance keeps the data inside your
infrastructure. Review monthly or quarterly:

- **Most-viewed pages** deserve the most care.
- **Pages with no views** need better discoverability or deletion.
- **High bounce rates** can mean the answer was found at once, or that the page failed. Ask
  the people who use it.

Search runs in the reader's browser and records nothing, so there is no report of what
people searched for. Questions asked in chat that the knowledge base already answers
are the next best signal.

## Next steps

Once the knowledge base is live behind your access layer:

1. Announce it, and link to it from the places people currently ask questions.
2. Watch page views and the questions people still ask in chat.
3. Encourage every person who finds a gap to open a pull request that fills it.
4. Keep the review cycles you set. The knowledge bases that last are the ones that change
   with how the team actually works.
