Skip to main content

Maintaining

Maintenance

Docs rot. Screenshots go stale, URLs break, features get renamed, instructions reference UIs that no longer exist. The maintenance rhythm that keeps a 300-page docs site from becoming a graveyard.

Good docs are a snapshot of the product at one moment. Product ships faster than docs write. Left alone, a docs site becomes a museum — 30% accurate, 70% describing features that were renamed, removed, or replaced. Users can't tell which 30% until they try each instruction.

This guide is about keeping docs fresh without treating maintenance as a second job.

What rots, how fast

Screenshots

Decay rate: months. Any UI redesign invalidates every screenshot in the affected flow. Check quarterly at minimum.

External links

Decay rate: weeks. 5-10% of external links in any large docs site break per year. Quarterly audits catch them.

Version-specific claims

Decay rate: days after a release. "In v2.3 we added..." is accurate for one release cycle, then potentially misleading.

API responses / field names

Decay rate: whenever the API changes. If you're auto-generating from OpenAPI, this stays fresh. If hand-written, it rots silently.

Third-party tool references

Decay rate: unpredictable. "Open Cloudflare's SSL settings" — Cloudflare redesigned the UI last month. You don't know until a user reports confusion.

Copy-paste code examples

Decay rate: with every library upgrade. Does npm install stripe@latest still produce the API from your example? Run examples quarterly.

The staleness signals

How you detect rot without re-reading every page every week:

1. "Last updated" dates

NookDocs shows Last updated: DATE at the bottom of every page, sourced from the last git commit touching the file. Flag pages not updated in 12+ months for review.

# Pages not touched in 12 months
find docs -name "*.mdx" -mtime +365 | head -20

Older = more likely stale. Doesn't mean bad — some reference docs stay correct for years. But it's the shortlist for the freshness audit.

2. Broken link reports

Weekly automated run:

# Internal + external link check
lychee --include-file-extensions=mdx docs/

Breaks here:

  • Internal 404s from page renames (should have been redirected) — see redirects.

  • External 404s from vendor link rot — replace with updated URL or Internet Archive snapshot.

Wire into CI so broken links block the build. Prevents new rot from shipping.

3. Support ticket URLs

Same signal as improving-docs — tickets referencing a specific docs page mean the page didn't answer the user. But ALSO a staleness signal when the complaint pattern is "the instructions don't match the current UI."

Filter support tickets monthly for phrases like:

  • "the button isn't where it says"

  • "the setting has moved"

  • "I don't see the option"

  • "outdated"

Each is a maintenance-flagged page.

4. Thumbs-down feedback with "outdated"

NookDocs's feedback widget surfaces these in the dashboard. One-click flag.

5. Your own team surprise

When an engineer reads the docs for their own feature and says "wait, this is wrong" — that's a stale page. Capture these immediately; don't trust team memory.

The quarterly freshness audit

Every ~12 weeks, 4-hour block:

List all pages last updated >12 months ago

Output from the find command above. Usually 10-50 pages for a mid-sized docs site.

Skim each page's title + first paragraph

Fast triage. Does the description still match the feature? Is the first paragraph still accurate? ~30 seconds per page.

Deep-read the pages that flagged in triage

Read the whole page. Note specific sentences that look suspicious. Usually 5-15 pages per audit.

Test every code example + link

Copy-paste into a fresh environment. Visit every external link. 80% of updates ship at this step.

Update or retire

Fresh content lands in the same commit that touched the page. Content no longer relevant gets retired — either deleted with a redirect, or kept as-is with a "This page covers v1 behaviour" banner.

Log in a tracker: date, page, change made, age of last update. Patterns emerge — which sections rot fastest, which writers' pages stay accurate longest.

Keeping screenshots current

The most tedious maintenance. Tactics ranked by effort:

Level 1 — manual quarterly recap

Four times a year, open every page with a screenshot, verify against the current UI. Retake stale ones. Takes a day per quarter for a mid-sized site.

Level 2 — annotations only

Don't capture the whole UI; capture a small region with an arrow/circle annotation. Less pixels to rot. When UI moves, re-capture the small region.

Level 3 — Mermaid / diagrams over screenshots

Architectural + conceptual content → Mermaid. Mermaid source doesn't rot with UI redesigns. See media guide.

Level 4 — automated Playwright capture

Script the screenshots. Checked into CI. Re-captured on every build. Roadmap item; not shipping in NookDocs yet but the pattern works today via playwright test --update-snapshots.

Versioning as a maintenance strategy

If a version will be supported for years, don't edit the version-1 docs into version-2 docs — use NookDocs's versioning to keep them separate.

{
  "versions": [
    { "version": "v2", "tag": "Latest", "default": true },
    { "version": "v1", "tag": "Deprecated", "status": "deprecated" }
  ]
}

Each version's docs live at its own URL prefix (/v1/... / /v2/...). The default version's URLs canonical; others carry canonical tags back to default. Enables:

  • Deprecation notices per version without editing the other version's content.

  • Per-version search (optional).

  • Clear link from /v1/rate-limits to "this page describes the v1 API — see /v2/rate-limits for the current behaviour."

When to retire a page

Not every page should live forever. Candidates for retirement:

  • Features that no longer exist — product was sunset, page doesn't apply anymore.

  • Tutorials for versions 2+ behind current — maintenance cost exceeds reader value.

  • Duplicate pages — two pages cover the same topic, one was written while you forgot the other existed.

  • Pages with no inbound links + near-zero traffic — nobody's reading; no one would notice it gone.

Retirement options:

  1. Hard delete — gone from repo + db + sitemap + llms.txt. Add a redirect so inbound links don't 404.

  2. Hide — frontmatter hidden: true. Page still renders at its URL; removed from sidebar + search + sitemap. For pages where URLs shouldn't 404 but shouldn't be discoverable.

  3. Banner + keep — add a prominent callout: "This page describes behaviour for Acme v1, which reached end-of-life 2025-06-01. See the current docs for v2+ content." Keep the content for readers who land via old links / search results.

The "latest commit" rule

Every page carries an implicit contract: the last git commit on this file is approximately when this content was last verified. Break the rule (e.g. a cosmetic commit that doesn't actually verify) and the Last updated footer lies.

Implication for edits:

  • Don't bulk-update timestamps without re-reading. If you're bumping the mtime just to avoid the "stale" triage, you're making the triage useless. Actually verify, then commit.

  • Small fixes are fine. Typo fixes, link updates, one-sentence additions — commit each. Git history becomes a maintenance log.

  • Avoid mass search-and-replace commits. A commit that touches 50 pages with one find-and-replace marks all 50 as "recently updated" — but didn't actually verify any. Flag these in commit messages so quarterly audits know.

Deprecation process

When a feature gets deprecated:

Mark the page in-situ

Add a banner callout at the top:

<Banner variant="warning">
  `colors.primary` is deprecated as of v2.4. Use `colors.light` /
  `colors.dark` instead. `colors.primary` continues to work through
  v3.0 (sunset 2026-12-01).
</Banner>

Update cross-references

Every page linking to the deprecated feature should mention the deprecation inline OR link to the new approach.

Add a migration section

On the page, a clear "## Migrating to replacement" section with before/after examples.

Update changelog

New <Update> entry in /changelog announcing the deprecation + sunset date.

Schedule the retirement

Calendar reminder for sunset date. On that date: hide or redirect the page, remove from nav, announce completion in the changelog.

Common maintenance mistakes

Maintenance tool checklist

Automate what you can:

  • CI link checkerlychee or similar runs on every PR. Broken links fail the build.

  • Sitemap auto-regen — NookDocs does this on every sync.

  • Deprecation calendar — Google Calendar entry for each sunset date. Ritual > memory.

  • Quarterly freshness audit reminder — recurring event, non-negotiable.

  • Feedback widget — always on. Thumbs-down with comment = maintenance signal.

  • Analytics dashboard — weekly skim for anomalies (bounce spikes, zero-result search growth).

  • Screenshot naming conventioncomponent-state-YYYYMM.png makes the most stale one obvious in a file browser.

Related

Was this page helpful?

Last updated August 11, 2026