@@ -20,82 +20,98 @@ export function generateDocumentationSidebar(): any {
2020 } ] ) ;
2121
2222 // Post-process sidebar to fix folder titles and extract descriptions from frontmatter
23- const fixFolderTitles = ( items : any [ ] ) : any [ ] => {
24- return items . map ( item => {
25- let frontmatter : Record < string , any > | undefined ;
23+ const fixFolderTitles = ( items : any [ ] , depth = 0 ) : any [ ] => {
24+ return items . map ( ( item , index ) => {
25+ try {
26+ let frontmatter : Record < string , any > | undefined ;
2627
27- // Fix folder links for proper active state detection
28- // VitePress normalizes "/tutorials/index.md" to "/tutorials/" (WITH trailing slash)
29- // The regex /(?:(^|\/)index)?\.(?:md|html)$/ captures the "/" before "index"
30- // So we must ensure sidebar links for index pages also have trailing slashes
31-
32- // IMPORTANT: Don't add leading slash - VitePress adds base path
33- // If we have "/tutorials/", VitePress makes it "//tutorials/" (external link!)
34-
35- if ( item . link && item . link . endsWith ( '/index.md' ) ) {
36- // Convert "tutorials/index.md" to "tutorials/"
37- item . link = item . link . replace ( / \/ i n d e x \. m d $ / , '/' ) ;
38- } else if ( item . link && item . link . startsWith ( '/' ) ) {
39- // Remove leading slash that vitepress-sidebar added
40- item . link = item . link . substring ( 1 ) ;
41- }
42-
43- // Now check if link needs trailing slash
44- if ( item . link && ! item . link . endsWith ( '/' ) ) {
45- const possibleIndexPath = path . join ( 'docs' , item . link , 'index.md' ) ;
46- if ( fs . existsSync ( possibleIndexPath ) ) {
47- // Add trailing slash: "tutorials" to "tutorials/"
48- item . link = item . link + '/' ;
28+ // Recursively fix nested items first (works regardless of whether this item has a link)
29+ if ( item . items && Array . isArray ( item . items ) ) {
30+ item . items = fixFolderTitles ( item . items , depth + 1 ) ;
4931 }
50- }
5132
52- // Check if this is a folder with index.md to read its frontmatter
53- const possibleIndexPath = path . join ( 'docs' , item . link , 'index.md' ) ;
54- if ( item . link && fs . existsSync ( possibleIndexPath ) ) {
55- try {
56- const content = fs . readFileSync ( possibleIndexPath , 'utf-8' ) ;
57- frontmatter = matter ( content ) . data ;
58- if ( frontmatter ?. title ) {
59- item . text = frontmatter . title ;
60- }
61- } catch ( err ) {
62- // Ignore errors, keep the original text
33+ // Skip processing if no link (section headers, collapsed groups, etc.)
34+ if ( ! item . link || typeof item . link !== 'string' ) {
35+ console . log ( `[sidebar] Skipping item without link: text="${ item . text } ", hasItems=${ ! ! item . items } ` ) ;
36+ return item ;
6337 }
64- } else if ( item . link && item . link . endsWith ( '.md' ) ) {
65- // This is a file link - read frontmatter from the page
66- const pagePath = path . join ( 'docs' , item . link ) ;
67- if ( fs . existsSync ( pagePath ) ) {
68- try {
69- const content = fs . readFileSync ( pagePath , 'utf-8' ) ;
70- frontmatter = matter ( content ) . data ;
71- } catch ( err ) {
72- // Ignore errors
38+
39+ // Fix folder links for proper active state detection
40+ // VitePress normalizes "/tutorials/index.md" to "/tutorials/" (WITH trailing slash)
41+ // The regex /(?:(^|\/)index)?\.(?:md|html)$/ captures the "/" before "index"
42+ // So we must ensure sidebar links for index pages also have trailing slashes
43+
44+ // IMPORTANT: Don't add leading slash - VitePress adds base path
45+ // If we have "/tutorials/", VitePress makes it "//tutorials/" (external link!)
46+
47+ if ( item . link . endsWith ( '/index.md' ) ) {
48+ // Convert "tutorials/index.md" to "tutorials/"
49+ item . link = item . link . replace ( / \/ i n d e x \. m d $ / , '/' ) ;
50+ } else if ( item . link . startsWith ( '/' ) ) {
51+ // Remove leading slash that vitepress-sidebar added
52+ item . link = item . link . substring ( 1 ) ;
53+ }
54+
55+ // Now check if link needs trailing slash
56+ if ( ! item . link . endsWith ( '/' ) ) {
57+ const possibleIndexPath = path . join ( 'docs' , item . link , 'index.md' ) ;
58+ if ( fs . existsSync ( possibleIndexPath ) ) {
59+ // Add trailing slash: "tutorials" to "tutorials/"
60+ item . link = item . link + '/' ;
7361 }
7462 }
75- } else if ( item . link && ! item . link . includes ( '.' ) ) {
76- // Link has no extension (vitepress-sidebar strips .md for leaf pages)
77- // Try appending .md to find the source file
78- const pagePath = path . join ( 'docs' , item . link + '.md' ) ;
79- if ( fs . existsSync ( pagePath ) ) {
63+
64+ // Check if this is a folder with index.md to read its frontmatter
65+ const possibleIndexPath = path . join ( 'docs' , item . link , 'index.md' ) ;
66+ if ( fs . existsSync ( possibleIndexPath ) ) {
8067 try {
81- const content = fs . readFileSync ( pagePath , 'utf-8' ) ;
68+ const content = fs . readFileSync ( possibleIndexPath , 'utf-8' ) ;
8269 frontmatter = matter ( content ) . data ;
70+ if ( frontmatter ?. title ) {
71+ item . text = frontmatter . title ;
72+ }
8373 } catch ( err ) {
84- // Ignore errors
74+ // Ignore errors, keep the original text
75+ }
76+ } else if ( item . link . endsWith ( '.md' ) ) {
77+ // This is a file link - read frontmatter from the page
78+ const pagePath = path . join ( 'docs' , item . link ) ;
79+ if ( fs . existsSync ( pagePath ) ) {
80+ try {
81+ const content = fs . readFileSync ( pagePath , 'utf-8' ) ;
82+ frontmatter = matter ( content ) . data ;
83+ } catch ( err ) {
84+ // Ignore errors
85+ }
86+ }
87+ } else if ( ! item . link . includes ( '.' ) ) {
88+ // Link has no extension (vitepress-sidebar strips .md for leaf pages)
89+ // Try appending .md to find the source file
90+ const pagePath = path . join ( 'docs' , item . link + '.md' ) ;
91+ if ( fs . existsSync ( pagePath ) ) {
92+ try {
93+ const content = fs . readFileSync ( pagePath , 'utf-8' ) ;
94+ frontmatter = matter ( content ) . data ;
95+ } catch ( err ) {
96+ // Ignore errors
97+ }
8598 }
8699 }
87- }
88100
89- if ( frontmatter ?. description ) {
90- item . description = frontmatter . description ;
91- }
101+ if ( frontmatter ?. description ) {
102+ item . description = frontmatter . description ;
103+ }
92104
93- // Recursively fix nested items
94- if ( item . items && Array . isArray ( item . items ) ) {
95- item . items = fixFolderTitles ( item . items ) ;
105+ return item ;
106+ } catch ( error ) {
107+ console . error ( `Error processing sidebar item at index ${ index } :` , {
108+ text : item . text ,
109+ link : item . link ,
110+ hasItems : ! ! item . items ,
111+ error : error instanceof Error ? error . message : String ( error )
112+ } ) ;
113+ throw error ; // Re-throw after logging
96114 }
97-
98- return item ;
99115 } ) ;
100116 } ;
101117
0 commit comments