@@ -221,7 +221,7 @@ export class Project {
221221 async getPageHtml ( loc : { pathname : string , search ?: string } ) : Promise < [ number , string ] > {
222222 if ( ! this . isSSRable ( loc . pathname ) ) {
223223 const [ url ] = this . #routing. createRouter ( loc )
224- return [ url . pagePath === '' ? 404 : 200 , this . getSPAIndexHtml ( ) ]
224+ return [ url . pagePath === '' ? 404 : 200 , await this . getSPAIndexHtml ( ) ]
225225 }
226226
227227 const { baseUrl } = this . config
@@ -241,16 +241,19 @@ export class Project {
241241 return [ status , html ]
242242 }
243243
244- getSPAIndexHtml ( ) : string {
244+ async getSPAIndexHtml ( ) {
245245 const { baseUrl, defaultLocale } = this . config
246246 const mainModule = this . #modules. get ( '/main.js' ) !
247+ const customLoading = await this . _renderLoadingPage ( )
247248 const html = createHtml ( {
248249 lang : defaultLocale ,
249250 scripts : [
251+ customLoading ?. data ? { type : 'application/json' , innerText : JSON . stringify ( customLoading ?. data ) , id : 'ssr-data' } : '' ,
250252 { src : path . join ( baseUrl , `/_aleph/main.${ mainModule . hash . slice ( 0 , hashShort ) } .js` ) , type : 'module' } ,
251253 { src : path . join ( baseUrl , `/_aleph/-/deno.land/x/aleph/nomodule.js${ this . isDev ? '?dev' : '' } ` ) , nomodule : true } ,
252254 ] ,
253- body : `<main></main>` , // todo: custom `loading` page
255+ head : customLoading ?. head || [ ] ,
256+ body : `<main>${ customLoading ?. body || '' } </main>` ,
254257 minify : ! this . isDev
255258 } )
256259 return html
@@ -291,7 +294,7 @@ export class Project {
291294
292295 // ssg
293296 const { ssr } = this . config
294- const SPAIndexHtml = this . getSPAIndexHtml ( )
297+ const SPAIndexHtml = await this . getSPAIndexHtml ( )
295298 if ( ssr ) {
296299 log . info ( colors . bold ( ' Pages (SSG)' ) )
297300 const paths = new Set ( this . #routing. paths )
@@ -520,6 +523,7 @@ export class Project {
520523 switch ( name . replace ( reModuleExt , '' ) ) {
521524 case 'app' :
522525 case '404' :
526+ case 'loading' :
523527 await this . _compile ( '/' + name )
524528 break
525529 }
@@ -1290,6 +1294,24 @@ export class Project {
12901294 return ret
12911295 }
12921296
1297+ private async _renderLoadingPage ( ) {
1298+ if ( this . #modules. has ( '/loading.js' ) ) {
1299+ const loadingModule = this . #modules. get ( '/loading.js' ) !
1300+ const { default : Loading } = await import ( 'file://' + loadingModule . jsFile )
1301+ const url = { locale : this . config . defaultLocale , pagePath : '' , pathname : '/' , params : { } , query : new URLSearchParams ( ) }
1302+ const [ html , data ] = await this . #renderer. renderPage ( url , undefined , undefined , [ { id : '/loading.js' , Component : Loading } ] )
1303+ const head = await this . #renderer. renderHead ( [
1304+ this . _lookupAsyncDeps ( loadingModule . id ) . filter ( ( { url } ) => reStyleModuleExt . test ( url ) )
1305+ ] . flat ( ) )
1306+ return {
1307+ head,
1308+ body : html ,
1309+ data,
1310+ } as RenderResult
1311+ }
1312+ return null
1313+ }
1314+
12931315 private _lookupAsyncDeps ( moduleID : string , __deps : { url : string , hash : string , async ?: boolean } [ ] = [ ] , __tracing : Set < string > = new Set ( ) ) {
12941316 const mod = this . getModule ( moduleID )
12951317 if ( ! mod ) {
0 commit comments