@@ -9,45 +9,195 @@ import type {GetServerSideProps} from 'next';
99import { siteConfig } from '../siteConfig' ;
1010import sidebarLearn from '../sidebarLearn.json' ;
1111import sidebarReference from '../sidebarReference.json' ;
12- import sidebarBlog from '../sidebarBlog.json' ;
1312
1413interface RouteItem {
1514 title ?: string ;
1615 path ?: string ;
1716 routes ?: RouteItem [ ] ;
17+ hasSectionHeader ?: boolean ;
18+ sectionHeader ?: string ;
1819}
1920
2021interface Sidebar {
2122 title : string ;
2223 routes : RouteItem [ ] ;
2324}
2425
25- function extractRoutes (
26+ interface Page {
27+ title : string ;
28+ url : string ;
29+ }
30+
31+ interface SubGroup {
32+ heading : string ;
33+ pages : Page [ ] ;
34+ }
35+
36+ interface Section {
37+ heading : string | null ;
38+ pages : Page [ ] ;
39+ subGroups : SubGroup [ ] ;
40+ }
41+
42+ // Clean up section header names (remove version placeholders)
43+ function cleanSectionHeader ( header : string ) : string {
44+ return header
45+ . replace ( / @ \{ \{ v e r s i o n \} \} / g, '' )
46+ . replace ( / - / g, ' ' )
47+ . split ( ' ' )
48+ . map ( ( word ) => word . charAt ( 0 ) . toUpperCase ( ) + word . slice ( 1 ) )
49+ . join ( ' ' )
50+ . trim ( ) ;
51+ }
52+
53+ // Extract routes for sidebars that use hasSectionHeader to define major sections
54+ // (like the API Reference sidebar)
55+ function extractSectionedRoutes (
2656 routes : RouteItem [ ] ,
2757 baseUrl : string
28- ) : { title : string ; url : string } [ ] {
29- const result : { title : string ; url : string } [ ] = [ ] ;
58+ ) : Section [ ] {
59+ const sections : Section [ ] = [ ] ;
60+ let currentSection : Section | null = null ;
3061
3162 for ( const route of routes ) {
32- if ( route . title && route . path ) {
33- result . push ( {
63+ // Skip external links
64+ if ( route . path ?. startsWith ( 'http' ) ) {
65+ continue ;
66+ }
67+
68+ // Start a new section when we hit a section header
69+ if ( route . hasSectionHeader && route . sectionHeader ) {
70+ if ( currentSection ) {
71+ sections . push ( currentSection ) ;
72+ }
73+ currentSection = {
74+ heading : cleanSectionHeader ( route . sectionHeader ) ,
75+ pages : [ ] ,
76+ subGroups : [ ] ,
77+ } ;
78+ continue ;
79+ }
80+
81+ // If no section started yet, skip
82+ if ( ! currentSection ) {
83+ continue ;
84+ }
85+
86+ // Route with children - create a sub-group
87+ if ( route . title && route . routes && route . routes . length > 0 ) {
88+ const subGroup : SubGroup = {
89+ heading : route . title ,
90+ pages : [ ] ,
91+ } ;
92+
93+ // Include parent page if it has a path
94+ if ( route . path ) {
95+ subGroup . pages . push ( {
96+ title : route . title ,
97+ url : `${ baseUrl } ${ route . path } .md` ,
98+ } ) ;
99+ }
100+
101+ // Add child pages
102+ for ( const child of route . routes ) {
103+ if ( child . title && child . path && ! child . path . startsWith ( 'http' ) ) {
104+ subGroup . pages . push ( {
105+ title : child . title ,
106+ url : `${ baseUrl } ${ child . path } .md` ,
107+ } ) ;
108+ }
109+ }
110+
111+ if ( subGroup . pages . length > 0 ) {
112+ currentSection . subGroups . push ( subGroup ) ;
113+ }
114+ }
115+ // Single page without children
116+ else if ( route . title && route . path ) {
117+ currentSection . pages . push ( {
34118 title : route . title ,
35119 url : `${ baseUrl } ${ route . path } .md` ,
36120 } ) ;
37121 }
38- if ( route . routes ) {
39- result . push ( ...extractRoutes ( route . routes , baseUrl ) ) ;
122+ }
123+
124+ // Don't forget the last section
125+ if ( currentSection ) {
126+ sections . push ( currentSection ) ;
127+ }
128+
129+ return sections ;
130+ }
131+
132+ // Extract routes for sidebars that use routes with children as the primary grouping
133+ // (like the Learn sidebar)
134+ function extractGroupedRoutes (
135+ routes : RouteItem [ ] ,
136+ baseUrl : string
137+ ) : SubGroup [ ] {
138+ const groups : SubGroup [ ] = [ ] ;
139+
140+ for ( const route of routes ) {
141+ // Skip section headers
142+ if ( route . hasSectionHeader ) {
143+ continue ;
144+ }
145+
146+ // Skip external links
147+ if ( route . path ?. startsWith ( 'http' ) ) {
148+ continue ;
149+ }
150+
151+ // Route with children - create a group
152+ if ( route . title && route . routes && route . routes . length > 0 ) {
153+ const pages : Page [ ] = [ ] ;
154+
155+ // Include parent page if it has a path
156+ if ( route . path ) {
157+ pages . push ( {
158+ title : route . title ,
159+ url : `${ baseUrl } ${ route . path } .md` ,
160+ } ) ;
161+ }
162+
163+ // Add child pages
164+ for ( const child of route . routes ) {
165+ if ( child . title && child . path && ! child . path . startsWith ( 'http' ) ) {
166+ pages . push ( {
167+ title : child . title ,
168+ url : `${ baseUrl } ${ child . path } .md` ,
169+ } ) ;
170+ }
171+ }
172+
173+ if ( pages . length > 0 ) {
174+ groups . push ( {
175+ heading : route . title ,
176+ pages,
177+ } ) ;
178+ }
179+ }
180+ // Single page without children - group under its own heading
181+ else if ( route . title && route . path ) {
182+ groups . push ( {
183+ heading : route . title ,
184+ pages : [
185+ {
186+ title : route . title ,
187+ url : `${ baseUrl } ${ route . path } .md` ,
188+ } ,
189+ ] ,
190+ } ) ;
40191 }
41192 }
42193
43- return result ;
194+ return groups ;
44195}
45196
46- const sidebars : Sidebar [ ] = [
47- sidebarLearn as Sidebar ,
48- sidebarReference as Sidebar ,
49- sidebarBlog as Sidebar ,
50- ] ;
197+ // Check if sidebar uses section headers as primary grouping
198+ function usesSectionHeaders ( routes : RouteItem [ ] ) : boolean {
199+ return routes . some ( ( r ) => r . hasSectionHeader && r . sectionHeader ) ;
200+ }
51201
52202export const getServerSideProps : GetServerSideProps = async ( { res} ) => {
53203 const subdomain =
@@ -60,14 +210,48 @@ export const getServerSideProps: GetServerSideProps = async ({res}) => {
60210 '> The library for web and native user interfaces.' ,
61211 ] ;
62212
213+ const sidebars : Sidebar [ ] = [
214+ sidebarLearn as Sidebar ,
215+ sidebarReference as Sidebar ,
216+ ] ;
217+
63218 for ( const sidebar of sidebars ) {
64219 lines . push ( '' ) ;
65220 lines . push ( `## ${ sidebar . title } ` ) ;
66- lines . push ( '' ) ;
67221
68- const routes = extractRoutes ( sidebar . routes , baseUrl ) ;
69- for ( const route of routes ) {
70- lines . push ( `- [${ route . title } ](${ route . url } )` ) ;
222+ if ( usesSectionHeaders ( sidebar . routes ) ) {
223+ // API Reference style: section headers define major groups
224+ const sections = extractSectionedRoutes ( sidebar . routes , baseUrl ) ;
225+ for ( const section of sections ) {
226+ if ( section . heading ) {
227+ lines . push ( '' ) ;
228+ lines . push ( `### ${ section . heading } ` ) ;
229+ }
230+
231+ // Output pages directly under section
232+ for ( const page of section . pages ) {
233+ lines . push ( `- [${ page . title } ](${ page . url } )` ) ;
234+ }
235+
236+ // Output sub-groups with #### headings
237+ for ( const subGroup of section . subGroups ) {
238+ lines . push ( '' ) ;
239+ lines . push ( `#### ${ subGroup . heading } ` ) ;
240+ for ( const page of subGroup . pages ) {
241+ lines . push ( `- [${ page . title } ](${ page . url } )` ) ;
242+ }
243+ }
244+ }
245+ } else {
246+ // Learn style: routes with children define groups
247+ const groups = extractGroupedRoutes ( sidebar . routes , baseUrl ) ;
248+ for ( const group of groups ) {
249+ lines . push ( '' ) ;
250+ lines . push ( `### ${ group . heading } ` ) ;
251+ for ( const page of group . pages ) {
252+ lines . push ( `- [${ page . title } ](${ page . url } )` ) ;
253+ }
254+ }
71255 }
72256 }
73257
0 commit comments