@@ -36,7 +36,9 @@ function buildBlogSidebarItems(): { text: string; link: string }[] {
3636 try {
3737 files = readdirSync ( blogDir )
3838 . filter ( ( f ) => f . endsWith ( ".md" ) && f !== "index.md" )
39- . toSorted ( ( a , b ) => compareVersionArrays ( parseBlogVersion ( a ) , parseBlogVersion ( b ) ) ) ;
39+ . toSorted ( ( a , b ) =>
40+ compareVersionArrays ( parseBlogVersion ( a ) , parseBlogVersion ( b ) ) ,
41+ ) ;
4042 } catch {
4143 // blog dir may not exist during the very first build
4244 }
@@ -116,10 +118,17 @@ export default defineConfig({
116118 "meta" ,
117119 {
118120 property : "og:image" ,
119- content : "https://fulll.github.io/github-code-search/social-preview.png" ,
121+ content :
122+ "https://fulll.github.io/github-code-search/social-preview.png" ,
123+ } ,
124+ ] ,
125+ [
126+ "meta" ,
127+ {
128+ property : "og:url" ,
129+ content : "https://fulll.github.io/github-code-search/" ,
120130 } ,
121131 ] ,
122- [ "meta" , { property : "og:url" , content : "https://fulll.github.io/github-code-search/" } ] ,
123132 // ── Twitter Card ────────────────────────────────────────────────────────
124133 [ "meta" , { name : "twitter:card" , content : "summary_large_image" } ] ,
125134 [ "meta" , { name : "twitter:title" , content : "github-code-search" } ] ,
@@ -135,7 +144,8 @@ export default defineConfig({
135144 "meta" ,
136145 {
137146 name : "twitter:image" ,
138- content : "https://fulll.github.io/github-code-search/social-preview.png" ,
147+ content :
148+ "https://fulll.github.io/github-code-search/social-preview.png" ,
139149 } ,
140150 ] ,
141151 ] ,
@@ -155,14 +165,47 @@ export default defineConfig({
155165 const { Resvg } = await import ( "@resvg/resvg-js" ) ;
156166 const { readFileSync, writeFileSync } = await import ( "node:fs" ) ;
157167 const { fileURLToPath } = await import ( "node:url" ) ;
158- const svgPath = fileURLToPath ( new URL ( "../public/social-preview.svg" , import . meta. url ) ) ;
159- const pngPath = fileURLToPath ( new URL ( "../public/social-preview.png" , import . meta. url ) ) ;
168+ const svgPath = fileURLToPath (
169+ new URL ( "../public/social-preview.svg" , import . meta. url ) ,
170+ ) ;
171+ const pngPath = fileURLToPath (
172+ new URL ( "../public/social-preview.png" , import . meta. url ) ,
173+ ) ;
160174 const svg = readFileSync ( svgPath , "utf-8" ) ;
161- const resvg = new Resvg ( svg , { fitTo : { mode : "width" , value : 1200 } } ) ;
175+ const resvg = new Resvg ( svg , {
176+ fitTo : { mode : "width" , value : 1200 } ,
177+ } ) ;
162178 writeFileSync ( pngPath , resvg . render ( ) . asPng ( ) ) ;
163179 } ,
164180 } ,
165181 ] ,
182+ // ── Chunk splitting ──────────────────────────────────────────────────────
183+ // Mermaid alone is >900 kB minified; split it + the d3 sub-tree into
184+ // dedicated async chunks to eliminate the Rollup 500 kB warning and
185+ // improve long-term caching. No generic vendor catch-all — VitePress
186+ // internals (mark.js etc.) need Rollup's default resolution.
187+ build : {
188+ // Mermaid (bundled with d3) is legitimately large (~2.4 MB minified).
189+ // 2500 kB threshold avoids the Rollup warning without masking real bloat
190+ // on other chunks (next largest is katex at ~260 kB).
191+ chunkSizeWarningLimit : 2500 ,
192+ rollupOptions : {
193+ output : {
194+ manualChunks ( id : string ) {
195+ // Mermaid + d3 must be co-located (circular dependency between them).
196+ if (
197+ id . includes ( "node_modules/mermaid" ) ||
198+ id . includes ( "node_modules/vitepress-plugin-mermaid" ) ||
199+ id . includes ( "node_modules/d3" ) ||
200+ id . includes ( "node_modules/dagre-d3-es" ) ||
201+ id . includes ( "node_modules/internmap" ) ||
202+ id . includes ( "node_modules/robust-predicates" )
203+ )
204+ return "mermaid" ;
205+ } ,
206+ } ,
207+ } ,
208+ } ,
166209 } ,
167210
168211 themeConfig : {
@@ -263,7 +306,10 @@ export default defineConfig({
263306 "/blog/" : [
264307 {
265308 text : "What's New" ,
266- items : [ { text : "All releases" , link : "/blog/" } , ...buildBlogSidebarItems ( ) ] ,
309+ items : [
310+ { text : "All releases" , link : "/blog/" } ,
311+ ...buildBlogSidebarItems ( ) ,
312+ ] ,
267313 } ,
268314 ] ,
269315 "/architecture/" : [
@@ -287,11 +333,14 @@ export default defineConfig({
287333 } ,
288334
289335 // ── Social ────────────────────────────────────────────────────────────────
290- socialLinks : [ { icon : "github" , link : "https://github.com/fulll/github-code-search" } ] ,
336+ socialLinks : [
337+ { icon : "github" , link : "https://github.com/fulll/github-code-search" } ,
338+ ] ,
291339
292340 // ── Edit link ─────────────────────────────────────────────────────────────
293341 editLink : {
294- pattern : "https://github.com/fulll/github-code-search/edit/main/docs/:path" ,
342+ pattern :
343+ "https://github.com/fulll/github-code-search/edit/main/docs/:path" ,
295344 text : "Edit this page on GitHub" ,
296345 } ,
297346
@@ -305,13 +354,20 @@ export default defineConfig({
305354 // ── Markdown ──────────────────────────────────────────────────────────────
306355 markdown : {
307356 theme : {
308- light : "github-light" ,
357+ // github-light-high-contrast fixes WCAG AA contrast for Shiki tokens
358+ // (github-light has #D73A49 4.24:1, #6A737D 4.46:1, #22863A 4.28:1 — all below 4.5:1)
359+ light : "github-light-high-contrast" ,
309360 dark : "github-dark" ,
310361 } ,
311362 } ,
312363
313364 // ── Sitemap ───────────────────────────────────────────────────────────────
365+ // VITEPRESS_HOSTNAME overrides the default for local/CI a11y audits:
366+ // VITEPRESS_HOSTNAME=http://localhost:4173 vitepress build docs
367+ // → sitemap.xml contains localhost URLs that pa11y-ci can reach directly.
314368 sitemap : {
315- hostname : "https://fulll.github.io/github-code-search/" ,
369+ hostname :
370+ ( process . env . VITEPRESS_HOSTNAME ?? "https://fulll.github.io" ) +
371+ "/github-code-search/" ,
316372 } ,
317373} ) ;
0 commit comments