DEV Community

Natália Kováč
Natália Kováč

Posted on Edited on

Editing headings in docs for readers who scan

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
Enter fullscreen mode Exit fullscreen mode

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?
Enter fullscreen mode Exit fullscreen mode

After:

Install on Linux
Install on Windows
Install on macOS
Enter fullscreen mode Exit fullscreen mode

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}")
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)