Most people don't read documentation from top to bottom. They land on a page, scan for the part that matches their problem, and read only that. The headings are what they scan. When I edit a docs page, I treat the headings as a separate piece of writing, and I edit them before I touch a single paragraph.
Read the headings on their own first
My first pass ignores the body text completely. I pull out just the headings and read them as a list, like a table of contents. For a Markdown file, I use a short Python script (more on it below), but copying them into a scratch file by hand works too.
Then I ask one question: if this list were all I saw, could I find the section I need? Here's a typical list from an install guide before editing:
Overview
Prerequisites
Install on macOS
Verify the install
Configuration
Advanced
Troubleshooting
It's not terrible, but "Overview", "Configuration" and "Advanced" don't tell a scanning reader much. Advanced what? Configuration of which part?
Name the task, not the category
Category labels like "Configuration" or "Usage" describe what kind of content sits underneath. Task headings describe what the reader can do with it. Readers arrive with a task in mind, so task headings match what they're looking for.
Some edits I make often:
- "Configuration" becomes "Set your API key and default region"
- "Usage" becomes "Run your first sync"
- "Advanced" becomes "Use a proxy server"
The edited headings are longer. That's fine. A heading that is a few words longer but tells me exactly what's below saves more time than it costs.
Put the distinctive words first
When people scan, they mostly read the start of each line. If five headings in a row begin with "How to", the eye has to travel past the same two words every time to find the difference.
So I move the words that tell sections apart to the front:
- "How to configure logging" becomes "Configure logging"
- "Information about rate limits" becomes "Rate limits and how to stay under them"
- "Steps for upgrading from version 2" becomes "Upgrade from version 2"
Starting with the verb or the key noun means the first word or two already identify the section.
Keep parallel headings parallel
Headings at the same level under the same parent are siblings, and readers compare them. If one sibling is a verb phrase, one is a noun and one is a question, the list feels uneven and harder to scan.
Before:
Installing on Linux
Windows
How do I install on macOS?
After:
Install on Linux
Install on Windows
Install on macOS
The edited version is a little repetitive, and that's the point. The repetition makes the one word that differs stand out.
Use the reader's words for problems
Troubleshooting sections are where headings matter most, because readers arrive with an error on their screen. A heading like "Path issues" makes them guess. A heading that quotes what they see, such as "command not found" after installing, lets them match it instantly, and it's also the text they're likely to search for.
A small script to list headings
This is the script I use for the first pass. It prints every H2 to H4 heading with its line number, indents by level, skips fenced code blocks (where # usually starts a comment), and marks a few headings I almost always end up rewriting:
import re
import sys
VAGUE = {"overview", "introduction", "general", "details", "notes",
"miscellaneous", "other", "more information", "advanced"}
in_code = False
with open(sys.argv[1], encoding="utf-8") as f:
for number, line in enumerate(f, start=1):
if line.startswith("`" * 3):
in_code = not in_code
continue
match = re.match(r"(#{2,4}) (.+)", line)
if in_code or not match:
continue
level, text = len(match.group(1)), match.group(2).strip()
flag = " <- vague" if text.lower() in VAGUE else ""
print(f"{number:>4} {' ' * (level - 2)}{text}{flag}")
Running python3 headings.py install.md on the guide above gives:
2 Overview <- vague
4 Prerequisites
5 Install on macOS
9 Verify the install
10 Configuration
11 Advanced <- vague
12 Troubleshooting
13 "command not found" after installing
The flag list is mine and deliberately short. A heading like "Overview" isn't always wrong; the flag is a prompt to check, not a verdict. The script also doesn't handle indented code blocks or headings written with underlines, which I rarely see in the docs I edit.
When to stop
I stop editing headings when the list on its own reads like a useful map of the page. Then I go back to the paragraphs, and often find that a clearer heading has already shown me which paragraphs belong somewhere else.
Top comments (0)