11import { themes as prismThemes } from "prism-react-renderer" ;
22import type { Config } from "@docusaurus/types" ;
33import type * as Preset from "@docusaurus/preset-classic" ;
4+ import * as fs from "fs" ;
5+ import * as path from "path" ;
46
57// This runs in Node.js - Don't use client-side code here (browser APIs, JSX...)
68
9+ function docsStaticAssetsPlugin ( ) {
10+ return {
11+ name : "docs-static-assets" ,
12+ configureWebpack ( config : any , isServer : boolean ) {
13+ // Only relocate for the production client build
14+ if ( isServer || config . mode !== "production" ) return { } ;
15+ // The CSS extractor is CssExtractRspackPlugin (with @docusaurus/faster) or
16+ // MiniCssExtractPlugin (plain webpack) — both names contain "CssExtract".
17+ for ( const plugin of config . plugins ?? [ ] ) {
18+ if ( plugin ?. constructor ?. name ?. includes ( "CssExtract" ) && plugin . options ) {
19+ plugin . options . filename = "docs_static/assets/css/[name].[contenthash:8].css" ;
20+ plugin . options . chunkFilename = "docs_static/assets/css/[name].[contenthash:8].css" ;
21+ }
22+ }
23+ return {
24+ output : {
25+ filename : "docs_static/assets/js/[name].[contenthash:8].js" ,
26+ chunkFilename : "docs_static/assets/js/[name].[contenthash:8].js" ,
27+ assetModuleFilename : "docs_static/assets/[name].[contenthash:8][ext]" ,
28+ } ,
29+ } ;
30+ } ,
31+ } ;
32+ }
33+
34+ // This plugin is to keep the redirect from foo to foo/ under our own
35+ // control, this emits a small `foo.html` stub at each no-slash path that redirects to the
36+ // canonical `/foo/` with a root-relative URL (resolves on airborne.juspay.in, never the
37+ // origin). Because `foo.html` exists, GitHub Pages serves it directly and never issues its
38+ // own leaking redirect.
39+ function noSlashRedirectStubsPlugin ( ) {
40+ return {
41+ name : "no-slash-redirect-stubs" ,
42+ async postBuild ( { outDir } : { outDir : string } ) {
43+ const indexFiles : string [ ] = [ ] ;
44+ ( function collect ( dir : string ) {
45+ for ( const e of fs . readdirSync ( dir , { withFileTypes : true } ) ) {
46+ const full = path . join ( dir , e . name ) ;
47+ if ( e . isDirectory ( ) ) collect ( full ) ;
48+ else if ( e . name === "index.html" ) indexFiles . push ( full ) ;
49+ }
50+ } ) ( outDir ) ;
51+ for ( const file of indexFiles ) {
52+ const relDir = path . relative ( outDir , path . dirname ( file ) ) ;
53+ if ( relDir === "" ) continue ;
54+ const urlPath = "/" + relDir . split ( path . sep ) . join ( "/" ) + "/" ;
55+ const stub = path . join ( outDir , relDir + ".html" ) ;
56+ if ( fs . existsSync ( stub ) ) continue ;
57+ fs . writeFileSync (
58+ stub ,
59+ `<!doctype html><html lang="en"><head><meta charset="utf-8">` +
60+ `<meta http-equiv="refresh" content="0; url=${ urlPath } ">` +
61+ `<title>Redirecting…</title></head>` +
62+ `<body>Redirecting to <a href="${ urlPath } ">${ urlPath } </a>…</body></html>\n` ,
63+ ) ;
64+ }
65+ } ,
66+ } ;
67+ }
68+
769const config : Config = {
870 title : "Airborne" ,
971 tagline : "Over-the-air updates for React Native, Android, and iOS" ,
10- favicon : "img/favicon.ico" ,
72+ favicon : "docs_static/ img/favicon.ico" ,
1173
1274 future : {
1375 v4 : true ,
@@ -90,6 +152,8 @@ const config: Config = {
90152 ] ,
91153
92154 plugins : [
155+ docsStaticAssetsPlugin ,
156+ noSlashRedirectStubsPlugin ,
93157 "docusaurus-plugin-sass" ,
94158 // Generates /llms.txt and /llms-full.txt at build time for LLM consumers.
95159 [
@@ -122,7 +186,7 @@ const config: Config = {
122186 themes : [ "docusaurus-theme-openapi-docs" , "@docusaurus/theme-mermaid" ] ,
123187
124188 themeConfig : {
125- image : "img/airborne-social-card.png" ,
189+ image : "docs_static/ img/airborne-social-card.png" ,
126190 mermaid : {
127191 theme : { light : "neutral" , dark : "dark" } ,
128192 } ,
@@ -140,8 +204,8 @@ const config: Config = {
140204 title : "" ,
141205 logo : {
142206 alt : "Airborne" ,
143- src : "img/airborne-logo-light.svg" ,
144- srcDark : "img/airborne-logo-dark.svg" ,
207+ src : "docs_static/ img/airborne-logo-light.svg" ,
208+ srcDark : "docs_static/ img/airborne-logo-dark.svg" ,
145209 href : "/docs" ,
146210 width : 132 ,
147211 } ,
0 commit comments