Skip to content

Make heading IDs local to page#437

Open
peterjeschke wants to merge 1 commit intoghostty-org:mainfrom
peterjeschke:patch-1
Open

Make heading IDs local to page#437
peterjeschke wants to merge 1 commit intoghostty-org:mainfrom
peterjeschke:patch-1

Conversation

@peterjeschke
Copy link

Fixes #436

Problem:

If you check https://ghostty.org/docs/features/applescript, https://ghostty.org/docs/install/release-notes/1-3-0 or https://ghostty.org/docs/install/release-notes/1-0-1, two of the pages will have a broken link to "Security" in the navigation on the right. Which page is not broken is random and is decided during build-time, based on which page is built first.

This because the heading id generator "remembers" ids to make sure they don't clash. If multiple headings have the same id, a counter is appended (e.g. security-2). However, there's a discrepancy: The heading id generator for the navigation only considers the headings on the current page when generating the navigation. However, the actual heading IDs are counted "globally" across all pages. As a result, two of the three example pages will have "security-2" and "security-3" as IDs, even though there is no other security heading on the page.

Solution

The quick fix is to make sure that the "encounteredIDs" map is scoped to the page (the "node" in remark-heading-ids.mjs" is effectively a page). Every page will have its own map.

Something to consider for the long-term would be to reduce the duplication of heading id generation. There are two separate implementations (one to generate the headings and one to generate the navigation), leading to this problem in the first place.

Proof that this didn't break anything

To check whether the de-duplication still works, visit https://ghostty.org/docs/install/build (or rather, your local or staging equivalent). This page has two headings "Dependencies", both which still have their correct IDs assigned after this change.

Fixes ghostty-org#436

# Problem:

If you check https://ghostty.org/docs/features/applescript, https://ghostty.org/docs/install/release-notes/1-3-0 or https://ghostty.org/docs/install/release-notes/1-0-1, two of the pages will have a broken link to "Security" in the navigation on the right. Which page is not broken is random and is decided during build-time, based on which page is built first.

This because the heading id generator "remembers" ids to make sure they don't clash. If multiple headings have the same id, a counter is appended (e.g. security-2). However, there's a discrepancy: The heading id generator for the navigation only considers the headings on the current page when generating the navigation. However, the actual heading IDs are counted "globally" across all pages. As a result, two of the three example pages will have "security-2" and "security-3" as IDs, even though there is no other security heading on the page.

# Solution

The quick fix is to make sure that the "encounteredIDs" map is scoped to the page (the "node" in remark-heading-ids.mjs" is effectively a page). Every page will have its own map.

Something to consider for the long-term would be to reduce the duplication of heading id generation. There are two separate implementations (one to generate the headings and one to generate the navigation), leading to this problem in the first place.

# Proof that this didn't break anything
To check whether the de-duplication still works, visit https://ghostty.org/docs/install/build (or rather, your local or staging equivalent). This page has two headings "Dependencies", both which still have their correct IDs assigned after this change.
@vercel
Copy link

vercel bot commented Mar 10, 2026

@peterjeschke is attempting to deploy a commit to the Ghostty Team on Vercel.

A member of the Team first needs to authorize it.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[ BUG ] Heading IDs are generated wrong, broken navigation

1 participant