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.
Problem
In assembler builds, navigation folders with the same relative path from different documentation sets were generating duplicate HTML
idattributes. This breaks the HTML specification and causes accessibility issues with<label for>and<input id>pairings in the navigation template (_TocTreeNav.cshtml).Example: Two docsets both have a
getting-startedfolder. When assembled, both folders received the same ID, causing invalid HTML.Root Cause
Navigation node IDs were generated using only the relative path:
FolderNavigation:ShortId.Create(parentPath)VirtualFileNavigation:ShortId.Create(RelativePathToDocumentationSet)TableOfContentsNavigation:ShortId.Create(parentPath)In assembler builds, multiple docsets can have folders with identical relative paths (e.g., both have
getting-started), resulting in duplicate IDs.Solution
Changed ID generation to include both the navigation root identifier and the URL:
ShortId.Create(NavigationRoot.Id, Index.Url)This ensures uniqueness because:
NavigationRoot.Idis unique per docset (based on project name)Index.Urlis unique within each docsetTesting
Added a test
NavigationNodeIdsAreUniqueAcrossDocsetsthat:SiteNavigation(production code)YieldAll()traversalThe test follows TDD: it fails with the original code and passes with the fix.