@@ -398,6 +398,89 @@ describe("initClientRouter", () => {
398398 await flush ( ) ;
399399 expect ( root . textContent ) . toContain ( "clicked" ) ;
400400 } ) ;
401+
402+ it ( "uses a document navigation for loader 404s instead of a shell boundary" , async ( ) => {
403+ const app = resolveApp (
404+ defineApp ( {
405+ shells : { public : "./shells/public.tsx" } ,
406+ routes : [
407+ route ( "/" , "./routes/home.tsx" , { id : "home" , render : "ssr" } ) ,
408+ route ( "/posts/:slug" , "./routes/post.tsx" , {
409+ id : "post" ,
410+ render : "ssr" ,
411+ shell : "public" ,
412+ } ) ,
413+ ] ,
414+ notFound : "./routes/not-found.tsx" ,
415+ } ) ,
416+ ) ;
417+ const originalLocation = window . location ;
418+ const documentNavigations : string [ ] = [ ] ;
419+ Object . defineProperty ( window , "location" , {
420+ configurable : true ,
421+ value : {
422+ ...window . location ,
423+ get href ( ) {
424+ return "http://localhost/" ;
425+ } ,
426+ set href ( value : string ) {
427+ documentNavigations . push ( value ) ;
428+ } ,
429+ hash : "" ,
430+ origin : "http://localhost" ,
431+ pathname : "/" ,
432+ search : "" ,
433+ } ,
434+ } ) ;
435+
436+ try {
437+ root . innerHTML = "<main>home</main>" ;
438+ fetchSpy . mockResolvedValue (
439+ createJsonResponse (
440+ {
441+ error : {
442+ message : "Post not found" ,
443+ name : "PrachtHttpError" ,
444+ status : 404 ,
445+ } ,
446+ } ,
447+ { status : 404 } ,
448+ ) ,
449+ ) ;
450+
451+ await initClientRouter ( {
452+ app,
453+ routeModules : {
454+ "./routes/home.tsx" : async ( ) => ( { default : ( ) => h ( "main" , null , "home" ) } ) ,
455+ "./routes/post.tsx" : async ( ) => ( { default : ( ) => h ( "main" , null , "post" ) } ) ,
456+ "./routes/not-found.tsx" : async ( ) => ( { default : ( ) => h ( "main" , null , "404" ) } ) ,
457+ } ,
458+ shellModules : {
459+ "./shells/public.tsx" : async ( ) => ( {
460+ Shell : ( { children } : { children : ComponentChildren } ) => h ( "section" , null , children ) ,
461+ ErrorBoundary : ( ) => h ( "p" , null , "shell boundary" ) ,
462+ } ) ,
463+ } ,
464+ initialState : {
465+ data : null ,
466+ routeId : "home" ,
467+ url : "/" ,
468+ } ,
469+ root,
470+ findModuleKey : ( _modules , file ) => file ,
471+ } ) ;
472+
473+ await window . __PRACHT_NAVIGATE__ ! ( "/posts/missing" ) ;
474+
475+ expect ( documentNavigations ) . toEqual ( [ "/posts/missing" ] ) ;
476+ expect ( root . textContent ) . not . toContain ( "shell boundary" ) ;
477+ } finally {
478+ Object . defineProperty ( window , "location" , {
479+ configurable : true ,
480+ value : originalLocation ,
481+ } ) ;
482+ }
483+ } ) ;
401484} ) ;
402485
403486describe ( "navigate() URL-scheme safety" , ( ) => {
0 commit comments