Skip to content

Add API topic pages under a Topics heading, preferring children: - #4628

Merged
akira28 merged 16 commits into
mainfrom
feature/api-topic-pages-decide
Oct 29, 2026
Merged

akira28 merged 16 commits into
mainfrom
feature/api-topic-pages-decide

Conversation

@akira28

@akira28 akira28 commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

The API Explorer now lists topic pages under a Topics sidebar heading, above the endpoint groups. The heading shows a product's children: pages first, then a page for each entry of the OpenAPI x-topics extension that no child page covers. bump.sh topic URLs such as /topic/topic-rate-limiting stop returning 404.

Affects: API reference, Configuration

Prompt summary: Fix elastic/docs-eng-team#820 and the docs-builder side of elastic/docs-eng-team#1104. The first decision in elastic/docs-eng-team#820 was to prefer x-topics and fall back to children:. After review, the team inverted it: the two sources are combined with priority to children: pages, and x-topics is deprecated, with the migration after GA. children: pages also carry pages such as the Elasticsearch API conventions in elastic/docs-eng-team#1135.

Why

Nothing parses x-topics, so the Kibana, Kibana serverless, and Elastic Cloud topic pages that bump.sh serves have no native page. Cloud Billing has no securitySchemes, so its /authentication page is not generated either: bump.sh builds it from an x-topics entry titled Authentication. The sitemap parity test reports these as 8 of the 14 missing pages in elastic/docs-eng-team#1104.

What

Topics sidebar heading

Topic pages sit under a Topics heading, in both the default and the preview navigation. The heading only appears when a product has at least one topic page. The breadcrumb folds it into the spec crumb, like an x-tagGroups heading.

children: pages first, then x-topics

The Topics heading lists the children: pages in the declared order, then the spec's topics. A child page covers a topic when its first heading matches the topic title or its text matches the topic content. A covered topic gets no page, so Kibana lists kibana-api-overview and builds no Kibana spaces topic page. The build writes no redirect pages for topics. elastic/docs-infra#493 redirects the bump.sh topic URLs, such as /topic/topic-kibana-spaces to kibana-api-overview. The child page keeps the replaced topic URLs as page names, so the version switcher still matches it with the topic page in a version that builds one.

x-topics pages

Each topic that no child covers renders at /topic/topic-<slug>, the same URL as on bump.sh. When two entries produce the same URL, the first one wins and the build logs a warning. Authentication comes first and Rate limiting second, and the other topics follow alphabetically. The pinned titles are one list, TopicsNavigationItem.PinnedTitles. topic joins the reserved slugs for children: files.

Authentication topic

A topic titled Authentication does not get its own topic page. Its content opens the /authentication page, above the security schemes, and that page is listed under Topics. elastic/docs-infra#493 redirects /topic/topic-authentication there, as on bump.sh. This also works for a spec without security schemes, which fixes cloud-billing/authentication.

Types is a heading, after a divider

Topics and Types are both page-less groups, so they share one sidebar heading type that points at the product overview. Types used to be a folder that linked to its first schema page; it now only expands. A divider sets Types apart from the endpoint groups, as one already does for Topics. Type page breadcrumbs lose the Types crumb, which linked to that first schema page.

Sitemap parity test

The test now mirrors the exact page redirects from elastic/docs-infra#493 and elastic/docs-infra#494. They cover the /servers pages, the renamed Cloud Billing budgets group, the topic URLs this PR builds no page for, and the Streams operations Kibana removed from its 9.6 spec. With this PR and both redirect PRs, every production API sitemap page resolves. Those redirects apply on staging and edge only, until the cutover.

Out of scope: Expanding the Topics heading by default is in #4629, on top of this PR. Moving x-topics content to children: pages is tracked in elastic/docs-eng-team#1144, after GA. Elasticsearch topic pages are tracked in elastic/docs-eng-team#1143 and elastic/docs-eng-team#1135. The landing page still does not show its topic list, as before.

Verify

dotnet test tests/Elastic.ApiExplorer.Tests/
# TopicPageTests — parsing, URLs, order, nav placement, children and topics union, Authentication merge, generated pages

To check the sitemap parity against a staging build:

dotnet run --project src/tooling/docs-builder -- assembler build --environment staging --no-assume-build
FEATURE_ASSEMBLER_API_EXPLORER=true dotnet run --project tests/Elastic.Documentation.Build.Tests/ -- --treenode-filter '/*/*/ApiSitemapParityTests/*'

Check on the preview

Topic URLs such as /topic/topic-kibana-spaces returned 404 because nothing
parsed the x-topics extension. Specs with x-topics now get one page per topic,
listed under a Topics sidebar heading above the endpoint groups. A topic named
Authentication becomes the /authentication page. The docset's children: pages
are only a fallback for specs without x-topics, and a replaced child redirects
to the topic with the same title.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@akira28
akira28 requested a review from a team as a code owner October 28, 2026 12:56
@akira28
akira28 requested a review from Mpdreamz October 28, 2026 12:56
akira28 and others added 2 commits October 28, 2026 13:59
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Spec order differed per product, so the same topic moved around between APIs.
Authentication and Rate limiting now come first, and the other topics follow
alphabetically. The pinned titles live in one list on TopicsNavigationItem.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@Mpdreamz Mpdreamz left a comment

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.

I'm hoping to migrate these to regular markdown pages instead.

Comment thread src/Elastic.ApiExplorer/Navigation/ApiNavigationBuilder.cs Outdated
Comment thread src/Elastic.ApiExplorer/Navigation/ApiNavigationBuilder.cs Outdated
Comment thread tests/Elastic.ApiExplorer.Tests/TopicPageTests.cs
Only x-topics follow the pinned and alphabetical order; children: pages keep
the order the docset declares. A child page headed Authentication now
redirects to /authentication instead of being dropped when the spec has an
Authentication topic. A generate test checks the topic pages and the
topic-authentication redirect on disk.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

Docs preview (local build)

Handbook preview: https://docs-v3-preview.elastic.dev/elastic/docs-builder/pull/4628/

Sample changed pages:

The team now deprecates x-topics in favour of children: pages, which render
through the full Markdown pipeline and can hold pages such as the
Elasticsearch API conventions. A product that declares children: lists those
pages under Topics and ignores the spec's x-topics. A topic URL redirects to
the child page with the same first heading, so bump.sh links keep working.
Products without children: still get their x-topics pages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@akira28 akira28 changed the title Render API topic pages from x-topics under a Topics heading Add API topic pages under a Topics heading, preferring children: Oct 28, 2026
@akira28

akira28 commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor Author

@Mpdreamz agreed, and this PR now follows that direction. We inverted the decision in elastic/docs-eng-team#820: children: pages take priority, and x-topics is deprecated.

  • The Topics heading lists the children: pages first, in the declared order, then the spec's x-topics.
  • A child page replaces a topic when its first heading matches the topic title or its text matches the topic content. The topic gets no page, and elastic/docs-infra#493 redirects its bump.sh URL to the child, so kibana/topic/topic-kibana-spaces forwards to kibana-api-overview.
  • Topics that no child covers still render, so the bump.sh URLs for Kibana serverless, Elastic Cloud, and Cloud Billing keep working until we move them.
  • We migrate the remaining x-topics content to children: pages after GA, in elastic/docs-eng-team#1144. Then x-topics support goes away.

The change is in 6b6d3bf, and 037490b leaves the redirects to docs-infra.

Comment thread src/Elastic.ApiExplorer/Navigation/ApiNavigationBuilder.cs Outdated
Topic pages are now the union of the docset's children: pages and the spec's
x-topics. A child page replaces a topic when its first heading matches the
topic title or its text matches the topic content, and the topic URL
redirects to it. Other topics still render, after the children: pages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The build no longer writes redirect pages for x-topics entries that a
children: page replaces, or for topic-authentication. Those bump.sh URLs
redirect in the CloudFront configuration in elastic/docs-infra, like the
other API page redirects. The sitemap parity test mirrors the new entries.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread src/Elastic.ApiExplorer/Navigation/ApiNavigationBuilder.cs Outdated
A children: page now answers to the URLs of the x-topics entries it replaces,
so the version switcher links it with the topic page another version still
builds. The build still writes no redirect pages for them. A child that
replaces the Authentication topic in a spec without security schemes logs a
warning, because /authentication then needs a redirect in elastic/docs-infra.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment thread src/Elastic.ApiExplorer/Navigation/ApiNavigationBuilder.cs Outdated
akira28 and others added 2 commits October 28, 2026 16:22
Another version builds an Authentication topic at /authentication, not at
/topic/topic-authentication. A child page that replaces that topic now also
answers to /authentication in the version switcher, unless its own spec
declares security schemes and so keeps a generated Authentication page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Topics heading is built in its own method, so CreateNavigation reads as
tags, schemas, topics, then structural pages. The spec's security schemes are
checked once, the Authentication name for the version switcher comes from a
small helper, and page collection skips any sidebar heading. The landing page
shares one row for topic, child, and structural pages, and two tests share a
helper for their child file. Behaviour is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
OpenApiTopic and ApiTopicPage carried the same title and content. The
x-topics parser now returns ApiTopicPage directly, and IsAuthentication is a
property of the page, so the builder hands the parsed topic straight to the
navigation item.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ApiMarkdown.RenderWithHeadings renders prose with anchors on its headings and
returns them for the table of contents, leaving out headings whose slug
another part of the page owns. The topic page and the Authentication topic
intro both use it instead of repeating the read, collect, and render steps.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ApiTopicsNavigationBuilder in Topics/ now builds the Topics heading, including
the children: pages, next to the topic page types. ApiNavigationBuilder makes
one call to it. Topic and child page URLs come from ApiUrlBuilder, and the
check whether a child page covers a topic is ApiTopicPage.IsCoveredBy.
Behaviour is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Topic titles that differ only in case or spacing, such as Rate limiting and
Rate Limiting, produced the same URL, and the later page silently replaced the
earlier one. The first entry now wins and the build logs a warning naming the
skipped entry. Two Authentication entries count as the same page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Topics and Types are both page-less groups of the API sidebar, so they share
ApiSidebarHeadingNavigationItem: a plain heading that points at the product
overview. Types was a folder that linked to its first schema page, and it now
expands without navigating. A divider sets Types apart from the endpoint
groups, as one already does for the topics. Type page breadcrumbs lose the
Types crumb, which linked to the first schema page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Both blocks after the Topics heading added a divider when something came
before them, then the block itself. AddSection does that once.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@akira28
akira28 added this pull request to stack #4631 October 29, 2026 08:44
@akira28
akira28 merged commit 7331858 into main Oct 29, 2026
36 checks passed
@akira28
akira28 deleted the feature/api-topic-pages-decide branch October 29, 2026 08:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants