Skip to main content

add-docs-page

Add, move, rename, or delete a page on the LangChain docs site. Covers choosing the source directory, writing frontmatter, placing the entry in src/docs.json navigation, adding redirects, and verifying with the lint and broken-link gates. Use when asked to add a new doc or page, move or rename a page, put something in the nav, or add a redirect.

Source facts

Repository
langchain-ai/docs
Last source activity
October 16, 2026 at 14:53
Detected SKILL.md language
English
Stars
433
Forks
2,744

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
add-docs-page
description
Add, move, rename, or delete a page on the LangChain docs site. Covers choosing the source directory, writing frontmatter, placing the entry in src/docs.json navigation, adding redirects, and verifying with the lint and broken-link gates. Use when asked to add a new doc or page, move or rename a page, put something in the nav, or add a redirect.
license
MIT
metadata
{"author":"langchain","version":"1.0"}
# Add or move a docs page A page is not finished when the MDX file exists. It also needs a navigation entry, and a move or deletion needs a redirect. CI enforces both. Read `AGENTS.md` for the navigation map, the style guide, and the frontmatter rules. This skill covers the procedure around them and does not repeat them. ## Step 1. Choose the source directory Use the "Source directory summary" table in `AGENTS.md` to go from subject to directory. Two traps: - Directory names do not match navigation names. `src/langsmith/fleet/` appears as "No-code agents"; `src/langsmith/managed-deep-agents*.mdx` appears under Build, not under a LangSmith menu. - Lifecycle menus mix products. Build draws from both `src/oss/` and `src/langsmith/`; Test, Deploy, and Monitor all draw from `src/langsmith/`. Never write to `build/`. It is Mintlify output, regenerated by `make build`. ## Step 2. Write the page Required frontmatter: ```yaml --- title: Clear, concise page title description: SEO summary with no markdown, no links, and no backticks --- ``` For OSS pages that differ by language, use `:::python` and `:::js` fences in one file rather than writing two files. The build pipeline emits both versions. ## Step 3. Add the navigation entry Navigation lives in `src/docs.json` under `navigation.products`. There are two products: `products[0]` is AGENT DEVELOPMENT LIFECYCLE (Home, Build, Test, Deploy, Monitor) and `products[1]` is PRODUCTS AND SETUP (LangSmith setup, LLM Gateway, No-code agents, Engine, Deep Agents Code). Each menu item is addressed by its `item` key, then nests one of two ways: - `menu[].tabs[].pages[]` for most menu items. - `menu[].dropdowns[].tabs[].pages[]` for Build, which has Python and TypeScript dropdowns. A `pages` array holds page-path strings and `{"group": ..., "pages": [...]}` objects, nested to any depth. Three rules: 1. **A language-versioned OSS page needs two entries.** Build page paths carry the language segment (`oss/python/deepagents/overview` and `oss/javascript/deepagents/overview`), so one new page means one entry in the Python dropdown and one in the TypeScript dropdown. Omitting the TypeScript entry is the most common miss. 2. **Page paths omit the `src/` prefix and the file extension.** `src/langsmith/sandboxes.mdx` is `"langsmith/sandboxes"`. 3. **A new group leads with an index page:** `"pages": ["group/index", "group/page"]`. Integration pages are the exception. Add them to the component's `index.mdx` instead, and touch `docs.json` only when creating a brand-new component group. ## Step 4. Add redirects for a move, rename, or deletion For a move or rename of a file that was already on `main`, run the repo's mover first. It rewrites cross-references across the corpus, which hand-editing misses: every link to the page in every form (`/oss/langchain/x`, `/oss/python/langchain/x`, `href="..."`), plus the `src/docs.json` nav entries and redirect destinations that name it: ```bash uv run docs mv src/langsmith/old-name.mdx src/langsmith/new-name.mdx --dry-run ``` Read any `Left ... links unchanged` warning in the output. It marks links the mover could not rewrite safely, such as an unversioned `/oss/integrations/...` link that also reaches the other language's page. Fix those by hand. Drop `--dry-run` once the preview looks right. The mover does not add a redirect, so add one to the `redirects` array in `src/docs.json`: ```json { "source": "/langsmith/old-name", "destination": "/langsmith/new-name" } ``` Redirect paths are site paths and start with `/`. A language-versioned page needs a redirect per language, plus one for the unversioned path if the old URL had one. `scripts/check_removed_pages_redirects.py` runs in CI and fails the PR when a page leaves the navigation and its source file is gone with no redirect. The same script fails when `docs.json` names a page whose file does not exist, so a typo in a page path is caught there rather than at build time. ## Step 4b. Two traps that fail silently ### Extract a snippet once a block appears on three pages `AGENTS.md` covers how to add a snippet. The rule for **when**: the same block repeated on three or more pages becomes one file under `src/snippets/`. A status callout duplicated across a page family means the wording change that retires it is an edit to every page in the family, and one will be missed. Verify a new snippet reaches the build. The pipeline rewrites snippet imports to language-specific paths, so `/snippets/langsmith/x.mdx` becomes `/snippets/python/langsmith/x.mdx` in the output, and a missing target renders as nothing at all rather than as an error: ```bash ls build/snippets/python/langsmith/<name>.mdx build/snippets/javascript/langsmith/<name>.mdx ``` ### Editing a heading moves its anchor A heading's slug is derived from its text, so rewording one silently breaks every `#anchor` link pointing at it, including links from other pages and entries in `src/docs.json`. Grep before editing: ```bash grep -rn 'use-with-the-langsmith-gateway' src/ --include=*.mdx --include=*.json ``` Changing only capitalization is safe, because slugs are lowercased. Changing a word is not, and needs either a reworded inbound link or a redirect. `<Step>` and `<Accordion>` accept an explicit `id`, which is how to keep a landing spot that is no longer a heading. ## Step 5. Verify Run all three, in this order: ```bash make lint_prose FILES="src/path/to/page.mdx" make build make broken-links-with-anchors ``` When `make build` fails with `Required uv version >=0.9.26 does not match the running version`, the local `uv` has drifted from the one `pyproject.toml` expects. Run the pipeline directly rather than working around the build: ```bash PYTHONPATH="$(pwd)" .venv/bin/python -m pipeline build ``` A fresh git worktree has no `.venv`, and the same version check blocks `uv sync` from creating one. Point at the main checkout's interpreter instead; `PYTHONPATH` still loads the pipeline code from the worktree: ```bash PYTHONPATH="$(pwd)" <main-checkout>/.venv/bin/python -m pipeline build ``` A fresh worktree's `.mise.toml` is also untrusted, so the first commit fails at the Vale hook with `Config files in <dir>/.mise.toml are not trusted`. Run `mise trust` once in the worktree. The `docs-edit` skill covers the permanent fix. `make broken-links-with-anchors` depends on `build`, so it fails the same way. Its link-check half runs on its own once the build output exists: ```bash cd build && mint broken-links --check-anchors | tee /tmp/bl.txt cd .. && python3 scripts/filter_mint_broken_links.py --check-anchors --input /tmp/bl.txt ``` Read `make broken-links-with-anchors` output by skipping to the `⎿` lines. Those are the only real failures. A bare filename with no indented lines beneath it is an OpenAPI-generated page that exists at deploy time but not locally. Fix every Vale finding. CI blocks on `lint_prose`, and its most common failure is a spaced em dash (`word — word` must be `word—word`). ## Step 6. Review the prose Once the edit is complete and before committing, invoke the `docs-review` skill on the files this pass changed. It runs in working-tree mode, so it needs no checkout, and it covers the style-guide rules Vale cannot see: passive voice, filler, product versus common noun capitalization, structure conventions, and link text. Run it on finished edits only. A review of a half-written section produces findings that go stale as soon as writing resumes. Skip this step for a change too small to have prose in it, such as a pure `docs.json` reorder or a redirect-only fix. ## Checklist - [ ] File in the directory the source-directory table names, not `build/`. - [ ] Frontmatter present, `description` free of markdown. - [ ] `src/docs.json` entry in the right product, menu item, tab, and group. - [ ] Both language entries added if the page is language-versioned. - [ ] Index page first if a new group was created. - [ ] Redirect added for every moved, renamed, or deleted path. - [ ] Inbound `#anchor` links checked before any heading was reworded. - [ ] A block now on three or more pages extracted to `src/snippets/`, and its built `python/` and `javascript/` targets confirmed to exist. - [ ] `make lint_prose` clean, `make broken-links-with-anchors` shows no new `⎿` lines. - [ ] `docs-review` run on the changed files, findings addressed.
View on GitHub