Fix navigator losing merged-archive root on direct page load (#1024) - #1032
Open
VictorPuga wants to merge 4 commits into
Open
VictorPuga wants to merge 4 commits into
VictorPuga wants to merge 4 commits into
Conversation
…ng#1024) extractRootModule flattened a root module together with its nested module children into one pool, then matched candidates against the current URL path. On a hard load of a member module's page (e.g. /documentation/alphakit/), that module's own path matched the URL and outranked its ancestor, so the synthesized package root and sibling modules were dropped from the navigator. Return the sole top-level module immediately when only one is provided, and only search nested descendants once no top-level candidate matches the URL, so a descendant can never outrank its own ancestor root.
1 of 2 tasks
marinaaisa
requested changes
Sep 30, 2026
marinaaisa
left a comment
Member
There was a problem hiding this comment.
Hi @VictorPuga ! thank you for your PR, I've been testing it and it enables DocC’s combined documentation within DocC Render.
Thank you for fixing the regression that reverted the intended functionality!
I added some comments to simplify the code. Thanks!
| // most of the time, it is expected that `data` always has a single item | ||
| // that represents the top-level root node of the navigation tree | ||
| // | ||
| const matchesRootPath = module => module.path.toLowerCase().endsWith(rootPath.toLowerCase()); |
Member
There was a problem hiding this comment.
Suggested change
| const matchesRootPath = module => module.path.toLowerCase().endsWith(rootPath.toLowerCase()); | |
| const matchesRootPath = ({ path }) => path.toLowerCase().endsWith(rootPath.toLowerCase()); |
Comment on lines
+209
to
+218
| const topLevelMatch = modules.find(matchesRootPath); | ||
| if (topLevelMatch) return topLevelMatch; | ||
|
|
||
| // otherwise, a matching root may be nested within one of the top-level | ||
| // modules—only fall back to searching nested modules once none of the | ||
| // top-level candidates themselves match, so a nested module can never | ||
| // outrank its own ancestor root | ||
| // | ||
| // otherwise, the first provided node will be used | ||
| return flattenedModules.length === 1 ? flattenedModules[0] : (flattenedModules.find(module => ( | ||
| module.path.toLowerCase().endsWith(rootPath.toLowerCase()) | ||
| )) ?? flattenedModules[0]); | ||
| // if nothing matches at all, the first provided module will be used | ||
| return flattenModules(modules).find(matchesRootPath) ?? modules[0]; |
Member
There was a problem hiding this comment.
Suggested change
| const topLevelMatch = modules.find(matchesRootPath); | |
| if (topLevelMatch) return topLevelMatch; | |
| // otherwise, a matching root may be nested within one of the top-level | |
| // modules—only fall back to searching nested modules once none of the | |
| // top-level candidates themselves match, so a nested module can never | |
| // outrank its own ancestor root | |
| // | |
| // otherwise, the first provided node will be used | |
| return flattenedModules.length === 1 ? flattenedModules[0] : (flattenedModules.find(module => ( | |
| module.path.toLowerCase().endsWith(rootPath.toLowerCase()) | |
| )) ?? flattenedModules[0]); | |
| // if nothing matches at all, the first provided module will be used | |
| return flattenModules(modules).find(matchesRootPath) ?? modules[0]; | |
| // in rare cases multiple top-level roots are provided | |
| // prefer the one whose path matches the current URL, then a matching | |
| // nested module, and finally the first module | |
| return modules.find(matchesRootPath) | |
| ?? flattenModules(modules).find(matchesRootPath) | |
| ?? modules[0]; |
Comment on lines
+206
to
+208
| // there may be rare, unexpected scenarios where multiple top-level root | ||
| // nodes are provide for some reason—if that happens, we would prefer the one | ||
| // with a path that most closely resembles the current URL path | ||
| // nodes are provided for some reason—if that happens, we would prefer the | ||
| // one with a path that most closely resembles the current URL path |
Member
There was a problem hiding this comment.
I would remove these comments.
Destructure path in matchesRootPath, collapse the fallback chain into a single return, and trim the redundant comments per review. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Contributor
Author
|
Comments were addressed |
Member
|
Wow - thank you both! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bug/issue #, if applicable: #1024
Summary
On a hard/direct load of a page belonging to a member module of a merged archive (e.g.
/documentation/alphakit/), the navigator dropped the synthesized package root and all sibling modules, showing only the module that matched the current URL. This happened becauseextractRootModuleflattened the root module together with its nested module children into a single pool before matching candidates against the URL path, so a member module's own path matched and outranked its ancestor root. This PR makesextractRootModulereturn the sole top-level module immediately when only one is provided, and only fall back to searching nested descendants once no top-level candidate matches the URL, so a descendant can never outrank its own ancestor root. Users navigating directly to a member module's documentation page will now see the full merged-archive navigator, including the package root and sibling modules, matching the behavior seen when navigating from the root page.Dependencies
None.
Testing
Steps:
Spec SDKroot withAlphaKitandBetaKitchildren, each with their own article)./documentation/alphakit/alphaarticle) as a hard/first load, not a client-side navigation from the root.AlphaKitandBetaKitas siblings, instead of only showingAlphaKit.Checklist
Make sure you check off the following items. If they cannot be completed, provide a reason.
npm test, and it succeeded