Skip to content

Fix #2995: Skip duplicate first header in sidebar header navigation#3039

Open
cobyfrombrooklyn-bot wants to merge 1 commit intorust-lang:masterfrom
cobyfrombrooklyn-bot:fix-issue-2995
Open

Fix #2995: Skip duplicate first header in sidebar header navigation#3039
cobyfrombrooklyn-bot wants to merge 1 commit intorust-lang:masterfrom
cobyfrombrooklyn-bot:fix-issue-2995

Conversation

@cobyfrombrooklyn-bot
Copy link

Problem

When a chapter's markdown file starts with a heading that matches the chapter title from SUMMARY.md, the sidebar header navigation (introduced in v0.5.0) shows a duplicate entry. For example:

<!-- SUMMARY.md -->
- [5.1 Keywords](./5_1_keywords.md)

<!-- 5_1_keywords.md -->
## 5.1 Keywords
Keywords are reserved words.
### 5.1.1 Raw Identifiers
...

The sidebar would show:

  • 5.1 Keywords (from SUMMARY.md, the chapter link)
    • 5.1 Keywords ← duplicate (from header nav scanning the h2)
      • 5.1.1 Raw Identifiers

This is a common pattern when authors use proper heading hierarchy (# for chapter title, ## for sections), as the reporter describes.

Fix

Added deduplication logic in the sidebar header navigation JS (toc.js.hbs). After collecting page headers, it compares the first header's text against the active sidebar entry. If they match (after normalizing whitespace and stripping the section number prefix like "1.1."), the first header is skipped.

The comparison handles:

  • Section number prefixes in the TOC (e.g., "1.1. 5.1 Keywords" → extracts "5.1 Keywords")
  • Whitespace normalization and case-insensitive matching
  • Only affects the first header; all subsequent headers are always shown

Test

Added duplicate_toc_header_skipped integration test with a minimal book that reproduces the issue (chapter title matching the first h2). Verifies the deduplication logic is present in the generated JS. Fails without the fix, passes with it.

Full test suite passes on macOS ARM (Apple Silicon): 270 tests, 0 failures.

@rustbot rustbot added the S-waiting-on-review Status: waiting on a review label Feb 25, 2026
When a chapter's markdown file starts with an h2 or lower heading (e.g.
`## Section Title`), the 'on this page' sidebar feature would add it as
a sub-entry, duplicating the chapter's existing SUMMARY.md sidebar link.

This skips the first heading in the on-this-page list when its text
matches the active sidebar link, preventing the duplication.

Fixes rust-lang#2995
@ehuss
Copy link
Contributor

ehuss commented Feb 27, 2026

I'm not quite convinced this is the right solution. Chapters are intended to start with a level-1 heading, and the TOC is designed around that.

@StefanSalewski
Copy link

I'm not quite convinced

Note that the actual issue was described in full detail in #2995 more than two months ago, and there has been no suggested solution or workaround.

@ehuss
Copy link
Contributor

ehuss commented Mar 1, 2026

I would suggest structuring your chapters so that each one starts with a level-1 heading if that heading is the name of the chapter.

@StefanSalewski
Copy link

I would suggest structuring your chapters so that each one starts with a level-1 heading if that heading is the name of the chapter.

Thanks for you reply. If I remember the actual issue, reported more than two months ago, correctly, the problem is not with chapter headings, but with the sections. For typically (english) books, chapters are typically divided by sections, where each section can be divided again into subsections. A chapter would start with a level 1 heading introduced with a single "#", and sections would start with a "##" level 2 heading. This is as it is done in LaTex and other tools like AsciiDoctor for decades, and that was working for MDBook before version 0.5. But now for version 0.5 we get duplicate TOC entries for the section headings, see

https://rust-for-c-programmers.com/

@StefanSalewski
Copy link

I had some hope that the authors of the official Rust book found some hack to suppress this issue, so I just tested it locally
mdbook05x
. But actually it gives the same problem, duplicated section headings in the TOC.

You can find the books source at https://github.com/rust-lang/book

Build with

$ mdbook build
$ firefox book/index.html                       # Linux

Actually, this result was expected, as they use correct section headings, as in

https://github.com/rust-lang/book/tree/main/src

## Functions

Functions are prevalent in Rust code. You’ve already seen one of the most
important functions in the language: the `main` function, which is the entry
point of many programs. You’ve also seen the `fn` keyword, which allows you to
declare new functions.

And as you can see in the appended screenshot, it is not an Firefox issue -- Google Chromium gives the same issue!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-review Status: waiting on a review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants