@@ -61,6 +61,7 @@ function createAngularMemoryPlugin(options) {
6161 map : mapContents && Buffer . from ( mapContents ) . toString ( 'utf-8' ) ,
6262 } ;
6363 } ,
64+ // eslint-disable-next-line max-lines-per-function
6465 configureServer ( server ) {
6566 const originalssrTransform = server . ssrTransform ;
6667 server . ssrTransform = async ( code , map , url , originalCode ) => {
@@ -124,14 +125,15 @@ function createAngularMemoryPlugin(options) {
124125 // Returning a function, installs middleware after the main transform middleware but
125126 // before the built-in HTML middleware
126127 return ( ) => {
128+ server . middlewares . use ( angularHtmlFallbackMiddleware ) ;
127129 function angularSSRMiddleware ( req , res , next ) {
128130 const url = req . originalUrl ;
129131 if ( ! req . url ||
130132 // Skip if path is not defined.
131133 ! url ||
132134 // Skip if path is like a file.
133- // NOTE: We use a regexp to mitigate against matching requests like: /browse/pl.0ef59752c0cd457dbf1391f08cbd936f
134- / ^ \. [ a - z ] { 2 , 4 } $ / i . test ( ( 0 , node_path_1 . extname ) ( url . split ( '?' ) [ 0 ] ) ) ) {
135+ // NOTE: We use a mime type lookup to mitigate against matching requests like: /browse/pl.0ef59752c0cd457dbf1391f08cbd936f
136+ lookupMimeTypeFromRequest ( url ) ) {
135137 next ( ) ;
136138 return ;
137139 }
@@ -227,3 +229,23 @@ function pathnameWithoutBasePath(url, basePath) {
227229 ? pathname . slice ( basePath . length - 1 )
228230 : pathname ;
229231}
232+ function angularHtmlFallbackMiddleware ( req , res , next ) {
233+ // Similar to how it is handled in vite
234+ // https://github.com/vitejs/vite/blob/main/packages/vite/src/node/server/middlewares/htmlFallback.ts#L15C19-L15C45
235+ if ( ( req . method === 'GET' || req . method === 'HEAD' ) &&
236+ ( ! req . url || ! lookupMimeTypeFromRequest ( req . url ) ) &&
237+ ( ! req . headers . accept ||
238+ req . headers . accept . includes ( 'text/html' ) ||
239+ req . headers . accept . includes ( 'text/*' ) ||
240+ req . headers . accept . includes ( '*/*' ) ) ) {
241+ req . url = '/index.html' ;
242+ }
243+ next ( ) ;
244+ }
245+ function lookupMimeTypeFromRequest ( url ) {
246+ const extension = ( 0 , node_path_1 . extname ) ( url . split ( '?' ) [ 0 ] ) ;
247+ if ( extension === '.ico' ) {
248+ return 'image/x-icon' ;
249+ }
250+ return extension && ( 0 , mrmime_1 . lookup ) ( extension ) ;
251+ }
0 commit comments