Skip to content

Add unified navigation extension and update component references#197

Merged
JakeSCahill merged 34 commits into
mainfrom
feature/unified-navigation
May 26, 2026
Merged

Add unified navigation extension and update component references#197
JakeSCahill merged 34 commits into
mainfrom
feature/unified-navigation

Conversation

@JakeSCahill
Copy link
Copy Markdown
Contributor

Adds the unified navigation extension for Data Platform unified sidebar and updates component references across all extensions.

Changes

New Extension

  • unified-navigation.js - Build-time extension that aggregates navigation from child components (Streaming, Connect) into a unified sidebar for Data Platform umbrella component

Component Reference Updates

Updates component names across all extensions to align with renamed components:

  • ROOTstreaming
  • redpanda-labslabs

Modified Extensions

  • algolia-indexer/generate-index.js - Update labs component reference
  • collect-bloblang-samples.js - Update streaming component reference
  • find-related-docs.js - Update streaming and labs component references
  • find-related-labs.js - Update streaming and labs component references
  • generate-fields-only-pages.js - Update component references
  • generate-rp-connect-categories.js - Update component references
  • generate-rp-connect-info.js - Update component references
  • unlisted-pages.js - Update component references

Part of unified navigation implementation.

Related PRs

  • docs: Multiple PRs for version branch renames (#1697-1704)
  • docs-ui: PR #376 (unified navigation UI)
  • cloud-docs: PR #578 (component home v3)

JakeSCahill and others added 6 commits May 8, 2026 12:42
Fixes two bugs in connector documentation generation:

1. CGO-only connectors incorrectly reported as "removed" - When processing
   intermediate versions, newData wasn't augmented with CGO connectors from
   binary analysis before diff generation, causing tigerbeetle_cdc, zmq4,
   ffi, etc. to appear as removed.

2. Cloud metadata inconsistency - New components like gcp_bigquery_write_api
   had cloudSupported: false in newComponents even when binary analysis
   correctly identified them as cloud-supported.

Changes:
- Add augmentConnectorData() helper function for reusable data augmentation
- Call augmentation before intermediate diff generation
- Save augmented data back to disk for subsequent iterations
- Refactor main augmentation to use the new helper function
Previously, cleanup kept versions based on current run's intermediate
processing results, which missed files from previous runs that were
committed to git.

Now cleanup:
- Sorts all versions by semver descending
- Keeps only the latest 2 versions
- Deletes all older JSON and CSV files

This ensures docs-data stays clean regardless of intermediate
processing history from previous automation runs.
When a connector page exists but the connector has been removed from
the CSV data (like the salesforce processor), the component_type_dropdown
macro now shows a clear message directing users to the release notes
for migration guidance instead of showing 'Available in: (blank)'.
Instead of hardcoding paths like '/redpanda-connect/get-started/whats-new/',
use Antora's contentCatalog.resolvePage() to dynamically resolve the
whats-new page URL. This generates proper relative URLs from the current
page and handles version/component variations automatically.

Falls back to hardcoded paths when contentCatalog is unavailable (e.g.,
during testing or preview builds).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Tests cover:
- Relative URL calculation from connector pages to whats-new
- Cloud vs self-managed context page spec generation
- Fallback behavior when contentCatalog unavailable
- Resolution behavior when contentCatalog available
- Macro registration without errors

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add unified-navigation.js extension for Data Platform unified sidebar
- Update ROOT → streaming component references across extensions
- Update redpanda-labs → labs component references
- Changes in: algolia-indexer, find-related-docs, find-related-labs, and other extensions

Part of unified navigation implementation.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 12, 2026

Review Change Stack

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 63628c63-fa4f-4f5a-bd22-5ba25f2db8b6

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR modernizes component naming across the documentation extensions ecosystem while introducing a major new unified-navigation feature. Component names are standardized: redpanda-labs becomes labs, redpanda-connect becomes connect, and redpanda-cloud becomes cloud-data-platform. A new 593-line unified-navigation extension registers an Antora hook to drive config-based page navigation and breadcrumb generation. The rp-connect-components macro gains a "connector unavailable" notice with dynamically resolved release-notes URLs, backed by a comprehensive test suite. The connector data handler is refactored to consolidate augmentation logic into a reusable helper and tighten version file retention. Package version increments to 4.18.0 with the new extension exported.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • micheleRP
  • paulohtb6
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 73.68% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main changes: adding a unified navigation extension and updating component name references across the codebase.
Description check ✅ Passed The description clearly outlines the new unified-navigation extension and documents all component reference updates across affected extensions.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/unified-navigation

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@netlify
Copy link
Copy Markdown

netlify Bot commented May 12, 2026

Deploy Preview for docs-extensions-and-macros ready!

Name Link
🔨 Latest commit 1636cb0
🔍 Latest deploy log https://app.netlify.com/projects/docs-extensions-and-macros/deploys/6a15bf7f8c892600080b634d
😎 Deploy Preview https://deploy-preview-197--docs-extensions-and-macros.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@JakeSCahill
Copy link
Copy Markdown
Contributor Author

JakeSCahill commented May 12, 2026

Jira: DOC-2180

Major changes:
- Rename page-header-data to component-metadata throughout
- Read navigation config from page-navigation attribute
- Support hierarchical navigation structure from config
- Compute breadcrumb hierarchy from navigation tree
- Attach page-breadcrumb-hierarchy to pages
- Remove section-based discovery (use explicit config)
- Support version detection for multi-version components
- Fallback to standard Antora nav when no config present

Config format in antora.yml:
  component-metadata:
    title: "Name"
    color: "#hex"
    icon: "icon-name"
    order: 10
  page-navigation:
    - component-name
    - parent: [child1, child2]

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@extensions/unified-navigation.js`:
- Line 90: Remove the noisy console.log call and the streaming-specific
logger.warn in extensions/unified-navigation.js: replace console.log(`[config]
Storing ${component.name}'s OWN config (root items:
${Array.from(allComponentsInConfig).join(', ')})`) with the extension's logger
at a trace/debug level (e.g., logger.debug or logger.trace) or remove it
entirely, and change any streaming home-page warning (logger.warn) to
logger.debug/trace so these messages can be silenced via log level; look for
other similar console.log calls and replace or remove them in the
config-resolution and filter helper code paths to avoid uncontrolled build
output.
- Around line 202-204: The summary log for processed config-driven pages is
using logger.warn which incorrectly signals a warning; change the call in the
block that checks configDrivenPages.size (the
Array.from(configDrivenPages).join(...) message) to use logger.info (or
logger.debug if you prefer lower verbosity) so the end-of-run summary is
informational rather than a warning, keeping the same message text and
interpolation.
- Around line 245-266: filterUnpublishedPages currently mutates Antora's shared
navigation by writing back into item.items; instead create and return a new tree
so you don't modify the original objects. Update filterUnpublishedPages (and its
recursive call) to map each item to a new object: if item.url and
publishedUrlsSet.has(item.url) keep a shallow copy of item but with items
replaced by the result of recursively calling filterUnpublishedPages on the
original item.items (when Array.isArray(item.items)); skip (return null) for
unpublished URLs and finally filter out nulls — never assign into item.items
in-place.
- Around line 320-326: The parseNavigationConfig function currently uses
JSON.parse to parse string navConfig which fails for the documented YAML format;
replace JSON.parse(navConfig) with yaml.load(navConfig) from the existing
js-yaml dependency (and add/import the yaml symbol if missing) so YAML strings
like "- streaming" are parsed correctly and still fallback to returning [] when
not an array.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ab59c6c9-485f-4464-9dd2-887bd784c666

📥 Commits

Reviewing files that changed from the base of the PR and between 4701aea and 3384edc.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (13)
  • __tests__/macros/rp-connect-components.test.js
  • extensions/algolia-indexer/generate-index.js
  • extensions/collect-bloblang-samples.js
  • extensions/find-related-docs.js
  • extensions/find-related-labs.js
  • extensions/generate-fields-only-pages.js
  • extensions/generate-rp-connect-categories.js
  • extensions/generate-rp-connect-info.js
  • extensions/unified-navigation.js
  • extensions/unlisted-pages.js
  • macros/rp-connect-components.js
  • package.json
  • tools/redpanda-connect/rpcn-connector-docs-handler.js

Comment thread extensions/unified-navigation.js Outdated
configOwner: component.name,
allComponents: allComponentsInConfig,
})
console.log(`[config] Storing ${component.name}'s OWN config (root items: ${Array.from(allComponentsInConfig).join(', ')})`)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Remove debug console.log calls and the streaming-specific debug warning.

console.log statements scattered across the config-resolution and filter helpers (and the targeted logger.warn for the streaming home page) look like leftover debugging that will flood the Antora build output on every run, with no way to silence them. They should go through the extension's logger at debug/trace level, or be removed.

🧹 Suggested cleanup
-                  console.log(`[config] Storing ${component.name}'s OWN config (root items: ${Array.from(allComponentsInConfig).join(', ')})`)
+                  logger.debug(`Storing ${component.name}'s OWN config (root items: ${Array.from(allComponentsInConfig).join(', ')})`)
@@
-                    console.log(`[config] Updating ${component.name}'s OWN config (better depth)`)
+                    logger.debug(`Updating ${component.name}'s OWN config (better depth)`)
@@
-          if (page.src.component === 'streaming' && page.src.path.includes('home/index')) {
-            logger.warn(
-              `Streaming home page: filtered tree has ${relevantTree.length} root items: ${relevantTree.map((t) => t.name).join(', ')}`
-            )
-          }
@@
-  const treeNames = configTree.map(t => t.name).join(', ')
-  console.log(`[filterConfigTreeForComponent] Called for ${componentName}, root items: [${treeNames}]`)
@@
-      console.log(`[filterConfigTreeForComponent] ${componentName}: FOUND at root level, hasChildren: ${!!item.children}`)
@@
-        console.log(`[filterConfigTreeForComponent] ${componentName}: returning parent with showNavItemsOnly + ${item.children.length} children`)
@@
-      console.log(`[filterConfigTreeForComponent] ${componentName}: no children, returning original tree`)
@@
-  console.log(`[filterConfigTreeForComponent] ${componentName}: NOT found at root, searching nested...`)

Also applies to: 102-102, 155-159, 396-396, 401-401, 406-406, 409-409, 414-414

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@extensions/unified-navigation.js` at line 90, Remove the noisy console.log
call and the streaming-specific logger.warn in extensions/unified-navigation.js:
replace console.log(`[config] Storing ${component.name}'s OWN config (root
items: ${Array.from(allComponentsInConfig).join(', ')})`) with the extension's
logger at a trace/debug level (e.g., logger.debug or logger.trace) or remove it
entirely, and change any streaming home-page warning (logger.warn) to
logger.debug/trace so these messages can be silenced via log level; look for
other similar console.log calls and replace or remove them in the
config-resolution and filter helper code paths to avoid uncontrolled build
output.

Comment on lines +202 to +204
if (configDrivenPages.size > 0) {
logger.warn(`Processed config-driven navigation for ${configDrivenPages.size} components: ${Array.from(configDrivenPages).join(', ')}`)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use an informational log level for the per-build summary.

This is a normal end-of-run summary, not a warning condition, but it's emitted at warn. In Antora pipelines that fail-on-warning or surface warning counts, this will produce noise and false positives on every build. Demote to info/debug.

-      if (configDrivenPages.size > 0) {
-        logger.warn(`Processed config-driven navigation for ${configDrivenPages.size} components: ${Array.from(configDrivenPages).join(', ')}`)
-      }
+      if (configDrivenPages.size > 0) {
+        logger.info(`Processed config-driven navigation for ${configDrivenPages.size} components: ${Array.from(configDrivenPages).join(', ')}`)
+      }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (configDrivenPages.size > 0) {
logger.warn(`Processed config-driven navigation for ${configDrivenPages.size} components: ${Array.from(configDrivenPages).join(', ')}`)
}
if (configDrivenPages.size > 0) {
logger.info(`Processed config-driven navigation for ${configDrivenPages.size} components: ${Array.from(configDrivenPages).join(', ')}`)
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@extensions/unified-navigation.js` around lines 202 - 204, The summary log for
processed config-driven pages is using logger.warn which incorrectly signals a
warning; change the call in the block that checks configDrivenPages.size (the
Array.from(configDrivenPages).join(...) message) to use logger.info (or
logger.debug if you prefer lower verbosity) so the end-of-run summary is
informational rather than a warning, keeping the same message text and
interpolation.

Comment on lines +245 to +266
function filterUnpublishedPages(items, publishedUrlsSet) {
if (!Array.isArray(items)) return []

return items
.map((item) => {
// If item has a URL, check if it's in the published URLs set
if (item.url) {
// Skip items whose pages aren't published
if (!publishedUrlsSet.has(item.url)) {
return null
}
}

// Recursively filter children
if (item.items && Array.isArray(item.items)) {
item.items = filterUnpublishedPages(item.items, publishedUrlsSet)
}

return item
})
.filter(Boolean) // Remove null entries
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

filterUnpublishedPages mutates Antora's shared navigation in place.

item.items = filterUnpublishedPages(item.items, publishedUrlsSet) on line 260 writes back into the navigation objects that came from version.navigation via componentVersionNavMap. The same navigation array is reused for every page of the same component/version (and is Antora's internal structure), so this side-effects shared state — affecting subsequent navigation consumers (other extensions, the standard sidebar, breadcrumb logic) and making the function order-dependent. Return a new tree instead of mutating in place.

🔒 Suggested fix (non-mutating)
 function filterUnpublishedPages(items, publishedUrlsSet) {
   if (!Array.isArray(items)) return []

   return items
-    .map((item) => {
-      // If item has a URL, check if it's in the published URLs set
-      if (item.url) {
-        // Skip items whose pages aren't published
-        if (!publishedUrlsSet.has(item.url)) {
-          return null
-        }
-      }
-
-      // Recursively filter children
-      if (item.items && Array.isArray(item.items)) {
-        item.items = filterUnpublishedPages(item.items, publishedUrlsSet)
-      }
-
-      return item
-    })
-    .filter(Boolean) // Remove null entries
+    .map((item) => {
+      if (item.url && !publishedUrlsSet.has(item.url)) {
+        return null
+      }
+      if (item.items && Array.isArray(item.items)) {
+        return { ...item, items: filterUnpublishedPages(item.items, publishedUrlsSet) }
+      }
+      return { ...item }
+    })
+    .filter(Boolean)
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function filterUnpublishedPages(items, publishedUrlsSet) {
if (!Array.isArray(items)) return []
return items
.map((item) => {
// If item has a URL, check if it's in the published URLs set
if (item.url) {
// Skip items whose pages aren't published
if (!publishedUrlsSet.has(item.url)) {
return null
}
}
// Recursively filter children
if (item.items && Array.isArray(item.items)) {
item.items = filterUnpublishedPages(item.items, publishedUrlsSet)
}
return item
})
.filter(Boolean) // Remove null entries
}
function filterUnpublishedPages(items, publishedUrlsSet) {
if (!Array.isArray(items)) return []
return items
.map((item) => {
if (item.url && !publishedUrlsSet.has(item.url)) {
return null
}
if (item.items && Array.isArray(item.items)) {
return { ...item, items: filterUnpublishedPages(item.items, publishedUrlsSet) }
}
return { ...item }
})
.filter(Boolean)
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@extensions/unified-navigation.js` around lines 245 - 266,
filterUnpublishedPages currently mutates Antora's shared navigation by writing
back into item.items; instead create and return a new tree so you don't modify
the original objects. Update filterUnpublishedPages (and its recursive call) to
map each item to a new object: if item.url and publishedUrlsSet.has(item.url)
keep a shallow copy of item but with items replaced by the result of recursively
calling filterUnpublishedPages on the original item.items (when
Array.isArray(item.items)); skip (return null) for unpublished URLs and finally
filter out nulls — never assign into item.items in-place.

Comment on lines +320 to +326
function parseNavigationConfig(navConfig) {
// If it's already an array (from YAML parsing), use it directly
const config = typeof navConfig === 'string' ? JSON.parse(navConfig) : navConfig

if (!Array.isArray(config)) {
return []
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check how page-navigation is actually supplied in this repo / fixtures and whether js-yaml is already used.
rg -nP -C2 "page-navigation" --type=yml --type=yaml --type=js
rg -nP "require\(['\"]js-yaml['\"]\)" --type=js

Repository: redpanda-data/docs-extensions-and-macros

Length of output: 977


🏁 Script executed:

# First, read the unified-navigation.js file to see the docstring, catch block, and full context
cat -n extensions/unified-navigation.js | head -330 | tail -100

Repository: redpanda-data/docs-extensions-and-macros

Length of output: 3734


🏁 Script executed:

# Search for page-navigation without restrictive type filters
rg -n "page-navigation" -C3

Repository: redpanda-data/docs-extensions-and-macros

Length of output: 4295


🏁 Script executed:

# Check if there are tests for this function
fd -i "test\|spec" -type f | xargs rg -l "parseNavigationConfig\|page-navigation" 2>/dev/null | head -20

Repository: redpanda-data/docs-extensions-and-macros

Length of output: 255


JSON.parse cannot parse the YAML format documented in the docstring.

The function documentation (lines 301–302) and example (lines 305–309) specify YAML input format, but line 322 uses JSON.parse() which only handles JSON. Any YAML string attribute (e.g., - streaming) will fail JSON parsing and be silently caught by the error handler at line 134, disabling navigation for that component without obvious indication.

Use yaml.load() from js-yaml (already a project dependency) instead of JSON.parse() to handle the documented YAML format correctly.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@extensions/unified-navigation.js` around lines 320 - 326, The
parseNavigationConfig function currently uses JSON.parse to parse string
navConfig which fails for the documented YAML format; replace
JSON.parse(navConfig) with yaml.load(navConfig) from the existing js-yaml
dependency (and add/import the yaml symbol if missing) so YAML strings like "-
streaming" are parsed correctly and still fallback to returning [] when not an
array.

JakeSCahill and others added 5 commits May 18, 2026 17:23
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add fallback indexing for landing pages (component-home-v3, data-platform layouts)
- Add special tag handling for umbrella components (Home, Data Platform, Self-Managed)
- Rename Self-Managed references to Streaming
- Filter umbrella components from home page tags
- Index landing pages using page metadata (title, description)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
… connect

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Copy link
Copy Markdown

@micheleRP micheleRP left a comment

Choose a reason for hiding this comment

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

Review

Critical

  1. In-place mutation of Antora's shared navigationextensions/unified-navigation.js:258. filterUnpublishedPages writes back via item.items = filterUnpublishedPages(...) into the same version.navigation arrays held by componentVersionNavMap, which is reused for every page of the component. Subsequent pages see the already-filtered (possibly empty) tree; other nav consumers see the mutation too. Fix: return a new tree, e.g.:

    return { ...item, items: filterUnpublishedPages(item.items, publishedUrlsSet) };
  2. Streaming-specific debug logger.warn left in productionextensions/unified-navigation.js:153-156. Cleanup commit 10 removed two console.logs but kept the

    if (page.src.component === 'streaming' && page.src.path.includes('home/index')) { logger.warn(...) }

    block. Hardcoded component name + spurious WARN per build. Fix: delete the block or drop to logger.debug.

Suggestions

  1. Summary log emitted at warnextensions/unified-navigation.js:201. Demote to info; it isn't a warning, and will inflate warning counts on every build.
  2. No tests for the new extension. __tests__/extensions/ covers four other extensions but not this one. parseNavigationConfig, getComponentDepth, isStandalone, filterConfigTreeForComponent, findComponentPath are all pure and trivially testable.
  3. Stray logger.warn debug instrumentation in extensions/unpublish-pages.js (lines 19-25, 35) — five lines per page with publish-only-during-beta plus one per unpublished page. Reads like leftover ADP beta debug.
  4. parseNavigationConfig string branch is dead — input is already parsed by Antora's YAML loader; the JSON.parse path doesn't fire.
  5. Hardcoded umbrella names in Algolia indexer['home', 'data platform', 'self-managed'] + ['home', 'component-home-v3', 'data-platform'] layouts. Extract to constants.

CodeRabbit triage (4 findings)

  • Keep: console.log + streaming-specific warn (cleanup commit 10 fixed two of the three; the streaming-home logger.warn block remains). Critical #2 above.
  • Keep: Summary log at warn. Suggestion #1 above. Demote to info.
  • Keep: filterUnpublishedPages mutates shared state. Most important finding. Critical #1 above.
  • Skip: page-navigation YAML / js-yaml analysis — input is already parsed by Antora's YAML loader, so the JSON.parse path doesn't fire. Dead code, not missing functionality.

Coordination risk

  • Breadcrumb computation depends on a component literally named 'home' (extensions/unified-navigation.js:138, componentConfigs.get('home')). If the docs-site playbook doesn't register an umbrella named exactly home, breadcrumbs silently no-op. (Verified — docs-site redpanda-data/docs-site#173 does register home as a component.)
  • Component-name updates across the eight modified extensions are consistent with the rollout (ROOT → streaming, redpanda-labs → labs).

See docs-site redpanda-data/docs-site#173 for cross-rollout notes (suggested approval order + verification steps).

Copy link
Copy Markdown

@micheleRP micheleRP left a comment

Choose a reason for hiding this comment

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

Approved on the assumption that the 2 Critical items in the review comment above are addressed before merge: (1) fix the filterUnpublishedPages in-place mutation at line 258 (return a new tree instead of writing back into the shared componentVersionNavMap), (2) delete or logger.debug-demote the streaming-specific debug logger.warn at lines 153-156. CodeRabbit triage + 5 non-blocking suggestions in the comment.

JakeSCahill and others added 7 commits May 26, 2026 08:20
When agentic-data-plane component is not included in the build, this extension
automatically redirects the home page to the data-platform landing page.

Supports both static HTML redirects and Netlify _redirects file.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Replace console.log/console.error with Antora logger in 8 extensions
- Add logger parameter support to version-fetcher utilities for proper logging
- Update component references from 'redpanda-connect' to 'connect'
- Add conditional-home-redirect to package.json exports
- Fix test expectations for renamed component

All 379 tests passing. Logging now respects Antora log levels (info, warn, error, debug).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Change streaming home-page logger.warn to logger.debug for less noise
- Change config-driven navigation summary from logger.warn to logger.info
- Fix filterUnpublishedPages to create new tree instead of mutating original
- Replace JSON.parse with yaml.load in parseNavigationConfig for YAML support
- Add js-yaml import for proper YAML parsing

All 379 tests passing. Navigation tree is now immutable and YAML configs work correctly.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Critical fixes:
- Fix filterUnpublishedPages to create new tree without mutating shared state
  Previously shallow copy still allowed mutation of componentVersionNavMap
  Now uses { ...item, items: recursiveCall() } pattern to ensure immutability
- Remove hardcoded streaming-specific debug block (lines 155-159)
  Production code should not have component-specific debug instrumentation

Additional cleanup:
- Change unpublish-pages debug logging from logger.warn to logger.debug (lines 20-25)
- Change unpublish action from logger.warn to logger.info (line 38)
  Reduces log noise - only actual unpublish actions are info-level

All 379 tests passing. Navigation tree mutation fixed, debug spam eliminated.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Fix: llms.adoc and sitemap pages should not trigger unlisted page warnings

Problem:
- llms.adoc is flagged as "unlisted page" even though it's intentionally not in navigation
- This page is converted to llms.txt at site root by convert-llms-to-txt extension
- The unpublish happens on 'beforePublish' event, after 'navigationBuilt' when unlisted-pages runs

Solution:
- Add exclusion list for technical pages that are intentionally unlisted
- Skip pages with stems: llms, sitemap, sitemap-llms
- These pages serve technical purposes (AI consumption, search engines) and shouldn't be in navigation

Result: No more spurious warnings for technical documentation artifacts

All 379 tests passing.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Changed 404 errors when fetching Chart.yaml to WARN level instead of ERROR,
with a clearer message explaining that the branch may not exist yet for
unreleased operator versions. This is expected behavior and not a critical error.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1. Filter large data attributes from markdown frontmatter
   - Added blocklist in convert-to-markdown.js to exclude massive objects
   - Prevents categories, csvData, and other component-level data from
     appearing in every page's frontmatter
   - Reduces markdown file sizes significantly for LLM consumption

2. Prepend component nav items in unified navigation
   - Data platform pages now show their own nav items (Overview, etc.)
     above child component buckets
   - Fixes missing navigation items for umbrella components

3. Improve operator version error messaging
   - Better warning when Docker Hub has version but GitHub branch doesn't exist
   - Clarifies this is expected for unreleased versions

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
JakeSCahill and others added 13 commits May 26, 2026 14:38
The previous fix prepended raw nav items to the buckets array, causing
the UI to render them with an empty bucket wrapper. Now wrapping parent
component's nav items in a pseudo-bucket with showNavItemsOnly: true,
which renders items directly without bucket header/wrapper.

This makes data-platform's Overview and Install MCP Server links appear
as regular nav items above the child component buckets.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Major version bump for breaking changes:
- Component rename: redpanda-connect → connect
- Unified navigation architecture
- Markdown frontmatter filtering

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1. Fix duplication bug where child component nav items appeared twice
   - Only top-level parent components (with children) should show their
     own nav items above child buckets
   - Child components (like streaming) should only show child buckets
   - Checks if component appears in relevantTree with children

2. Add better error handling for YAML parsing
   - Catch and log YAML parse errors with context
   - Helps debug "Unexpected token ':'" errors

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Moved page-support-months into attrs object where it belongs.
The previous conflict resolution had it as a stray line after Object.assign.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The isTopLevelParent check was looking at relevantTree (filtered for current
component) instead of the original configTree. This caused it to miss
data-platform's children, hiding its nav items.

Now uses componentHasChildren() helper to check the full configTree, which
correctly identifies data-platform as having children (cloud-data-platform,
self-managed) and shows its nav items (Overview, Install MCP Server).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Only show component nav items outside buckets if BOTH conditions are true:
1. Component has children (defines child buckets)
2. Component owns the config (defined page-navigation in its own antora.yml)

This fixes:
- data-platform: has children + owns config → shows nav items ✓
- self-managed: has children but inherits config → nav items stay in bucket ✓
- streaming: no children + inherits config → no duplication ✓

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
When a component has children and owns its config (like data-platform or
self-managed), its nav items should appear outside buckets, not inside.

Before: relevantTree included parent + children, buildBucketsFromConfig
created buckets for ALL including parent → duplication

After: When hasChildren && ownsConfig, extract only children for bucket
building, parent's nav items shown outside buckets only

Results:
- data-platform: nav items above buckets ✓
- self-managed: nav items above buckets, no duplication ✓
- streaming: no duplication ✓

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Tests added:
✓ Components without page-navigation use standard nav
✓ Child components don't duplicate nav items
✓ Standalone components use standard nav
✗ Parent component nav items (needs debugging)
✗ Unpublished page filtering (needs setup fix)

The parent component test is failing because treeForBuckets extraction
isn't working correctly - still includes parent in buckets.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Added logs to trace:
- Which children are extracted for bucket building
- Whether parent nav items condition passes
- How many nav items are found and added

This will help diagnose why data-platform nav items aren't showing
and why self-managed has duplicate Overview.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The bug: filterConfigTreeForComponent sets children: undefined on parent
nodes, so we couldn't extract children from the filtered relevantTree.

The fix: Extract children from the original configData.configTree instead
of the filtered tree.

Added findNodeInTree() helper to recursively find nodes in the tree.
Simplified componentHasChildren() to use findNodeInTree().

This should fix:
- data-platform: nav items now extracted properly
- self-managed: nav items now extracted properly
- No more "couldn't extract them from relevantTree" warnings

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Cleaned up excessive debug logs added during troubleshooting.
Kept only essential error/warning logs.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The test was using a standalone component config which doesn't trigger
custom navigation. Updated to use a parent-child config so custom nav
is applied and unpublished page filtering can be tested.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@JakeSCahill JakeSCahill merged commit 1568bb1 into main May 26, 2026
24 checks passed
@JakeSCahill JakeSCahill deleted the feature/unified-navigation branch May 26, 2026 15:51
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.

2 participants