Skip to content

fix: do not render headings with no content#944

Open
moshams272 wants to merge 1 commit into
nodejs:mainfrom
moshams272:feat/optional-heading-render
Open

fix: do not render headings with no content#944
moshams272 wants to merge 1 commit into
nodejs:mainfrom
moshams272:feat/optional-heading-render

Conversation

@moshams272

@moshams272 moshams272 commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Description

Currently, if an MDX page lacks an ATX H1 (e.g., when the h1 is built into a custom React component), doc-kit automatically injects an empty h1 to satisfy AST structural requirements and metadata generation.

However, this leads to an issue for MDX: if it renders its own custom h1 in a React component, the final HTML ends up with two h1 tags (one from doc-kit, one from the component), breaking SEO and Accessibility.

The current workaround involves forcing a # Heading in markdown and visually hiding it via CSS (sr-only), which is a hack.

This PR still injects an empty h1, but it doesn't render the empty headings in general to DOM.

Validation

Tested on webpack-doc-kit:

Before:
image

After:
image

Related Issues

None

Check List

  • I have read the Contributing Guidelines and made commit messages that follow the guideline.
  • I have run node --run test and all tests passed.
  • I have check code formatting with node --run format & node --run lint.
  • I've covered new added functionality with unit tests if necessary.

@moshams272
moshams272 requested a review from a team as a code owner July 26, 2026 20:36
@vercel

vercel Bot commented Jul 26, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
api-docs-tooling Ready Ready Preview Jul 26, 2026 10:05pm

Request Review

@vercel

vercel Bot commented Jul 26, 2026

Copy link
Copy Markdown

@moshams272 is attempting to deploy a commit to the OpenJS Foundation Team on Vercel.

A member of the Team first needs to authorize it.

@cursor

cursor Bot commented Jul 26, 2026

Copy link
Copy Markdown

PR Summary

Low Risk
Small rendering and documentation-spec change; behavior only affects pages with no headings or empty synthetic titles, with no auth or data impact.

Overview
MDX/custom layouts no longer get a visible duplicate h1 when the page has no ATX title: parse.mjs still prepends an empty depth-1 heading for structure/metadata, and createHeadingElement in buildContent.mjs now returns an empty text node instead of a heading wrapper when that heading has no children.

The spec (docs/specification.md §3.1) changes the document title heading from REQUIRED to OPTIONAL, aligning the formal rules with pages that supply their own title in React.

The parser comment clarifies that the injected heading is structural only and is not rendered.

Reviewed by Cursor Bugbot for commit bee146c. Bugbot is set up for automated code reviews on this repo. Configure here.

@codecov

codecov Bot commented Jul 26, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 50.00000% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.18%. Comparing base (7bd1b5b) to head (bee146c).

Files with missing lines Patch % Lines
src/generators/jsx-ast/utils/buildContent.mjs 40.00% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #944      +/-   ##
==========================================
- Coverage   86.20%   86.18%   -0.02%     
==========================================
  Files         195      195              
  Lines       17674    17679       +5     
  Branches     1608     1609       +1     
==========================================
+ Hits        15235    15237       +2     
- Misses       2433     2436       +3     
  Partials        6        6              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit a0c54a2. Configure here.

Comment thread src/generators/jsx-ast/utils/buildContent.mjs Outdated
@avivkeller

Copy link
Copy Markdown
Member

Can you:

  1. Make this not an option, we shouldn't render elements with no content in any case
  2. Patch the docs + spec to remove the note about titleless pages?

@moshams272

Copy link
Copy Markdown
Contributor Author

Can you:

  1. Make this not an option, we shouldn't render elements with no content in any case
  2. Patch the docs + spec to remove the note about titleless pages?

you mean for headings only, right?

@avivkeller

Copy link
Copy Markdown
Member

yes sorry

@moshams272
moshams272 force-pushed the feat/optional-heading-render branch from a0c54a2 to bee146c Compare July 26, 2026 22:04
@moshams272 moshams272 changed the title feat: support hide_title in frontmatter to skip the default h1 created fix: do not render headings with no content Jul 26, 2026
Comment on lines +90 to 93
// If the document has no headings but it has content, we add a fake heading to the top, it will not be rendered
if (headingNodes.length === 0 && tree.children.length > 0) {
tree.children.unshift(createTree('heading', { depth: 1 }, []));
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we just remove this statement... Why are we adding a fake heading in the first place?

Then, createHeadings won't need a fast path

@bmuenzenmeyer

Copy link
Copy Markdown
Contributor

this feels very related to notions within #931

@avivkeller

Copy link
Copy Markdown
Member

this feels very related to notions within #931

Sort of, yes. We have one page without a heading, since we add the heading via JSX

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.

3 participants