@@ -75,6 +75,34 @@ if (fs.existsSync(staticPath)) {
7575 return res . status ( 404 ) . send ( '// env-config not found' ) ;
7676 } ) ;
7777
78+ // Serve runtime-config.js (generated at container startup) if present,
79+ // otherwise generate a minimal runtime-config from env vars to help the
80+ // browser when runtime-config.js is missing from the static bundle.
81+ app . get ( '/runtime-config.js' , ( _req : Request , res : Response ) => {
82+ const file = path . join ( staticPath , 'runtime-config.js' ) ;
83+ if ( fs . existsSync ( file ) ) {
84+ // Ensure we send correct JS content type for static file
85+ res . type ( 'application/javascript' ) ;
86+ return res . sendFile ( file ) ;
87+ }
88+
89+ // Build runtime config from VITE_ env vars (fall back to empty strings)
90+ const runtime = {
91+ VITE_BACKEND_BASE_URL : process . env . VITE_BACKEND_BASE_URL || '' ,
92+ VITE_LOGIN_BASE_URL : process . env . VITE_LOGIN_BASE_URL || '' ,
93+ VITE_NODE_ENV : process . env . VITE_NODE_ENV || 'production' ,
94+ VITE_OAUTH_WEB_CLIENT_ID : process . env . VITE_OAUTH_WEB_CLIENT_ID || '' ,
95+ VITE_OAUTH_WEB_CLIENT_SECRET : process . env . VITE_OAUTH_WEB_CLIENT_SECRET ? 'SET' : '' ,
96+ _generated : new Date ( ) . toISOString ( ) ,
97+ } as Record < string , any > ;
98+
99+ const content = `// Runtime configuration (generated)\nwindow.runtimeConfig = ${ JSON . stringify (
100+ runtime ,
101+ ) } ;\n`;
102+ res . type ( 'application/javascript' ) ;
103+ return res . status ( 200 ) . send ( content ) ;
104+ } ) ;
105+
78106 // SPA fallback: only serve index.html for GET requests that accept HTML,
79107 // and explicitly exclude API and diagnostic routes so API clients get JSON.
80108 app . get ( "/*" , ( req : Request , res : Response , next : NextFunction ) => {
0 commit comments