@@ -16,15 +16,14 @@ import type { ComponentType } from 'react';
1616 * WordPress dependencies
1717 */
1818import { __ } from '@wordpress/i18n' ;
19- import { lazy , Suspense , useMemo } from '@wordpress/element' ;
19+ import { lazy , useState , useEffect } from '@wordpress/element' ;
2020import { Page } from '@wordpress/admin-ui' ;
2121
2222/**
2323 * Internal dependencies
2424 */
2525import Root from '../root' ;
2626import type { Route , RouteLoaderContext } from '../../store/types' ;
27- import * as homeRoute from '../home' ;
2827
2928// Not found component
3029function NotFoundComponent ( ) {
@@ -48,16 +47,12 @@ function RouteComponent( {
4847 < >
4948 { Stage && (
5049 < div className = "boot-layout__stage" >
51- < Suspense fallback = { < div > Loading...</ div > } >
52- < Stage />
53- </ Suspense >
50+ < Stage />
5451 </ div >
5552 ) }
5653 { Inspector && (
5754 < div className = "boot-layout__inspector" >
58- < Suspense fallback = { < div > Loading...</ div > } >
59- < Inspector />
60- </ Suspense >
55+ < Inspector />
6156 </ div >
6257 ) }
6358 </ >
@@ -71,16 +66,14 @@ function RouteComponent( {
7166 * @param parentRoute Parent route.
7267 * @return Tanstack Route.
7368 */
74- function createRouteFromDefinition ( route : Route , parentRoute : AnyRoute ) {
75- if ( ! route . content && ! route . content_module ) {
76- throw new Error ( 'Route must have content or content_module property' ) ;
77- }
78-
69+ async function createRouteFromDefinition (
70+ route : Route ,
71+ parentRoute : AnyRoute
72+ ) {
7973 // Create lazy components for stage and inspector surfaces
80- const SurfacesModule = route . content
81- ? ( ) => < RouteComponent { ...route . content } />
82- : lazy ( async ( ) => {
83- const module = await import ( route . content_module as string ) ;
74+ const SurfacesModule = route . content_module
75+ ? lazy ( async ( ) => {
76+ const module = await import ( route . content_module ! ) ;
8477 // Return a component that renders the surfaces
8578 return {
8679 default : ( ) => (
@@ -90,27 +83,39 @@ function createRouteFromDefinition( route: Route, parentRoute: AnyRoute ) {
9083 />
9184 ) ,
9285 } ;
93- } ) ;
86+ } )
87+ : ( ) => null ;
88+
89+ // Load route module for lifecycle functions if specified
90+ let routeConfig : {
91+ beforeLoad ?: ( context : RouteLoaderContext ) => void | Promise < void > ;
92+ loader ?: ( context : RouteLoaderContext ) => Promise < unknown > ;
93+ } = { } ;
94+
95+ if ( route . route_module ) {
96+ const module = await import ( route . route_module ) ;
97+ routeConfig = module . route || { } ;
98+ }
9499
95100 return createRoute ( {
96101 getParentRoute : ( ) => parentRoute ,
97102 path : route . path ,
98- beforeLoad : route . beforeLoad
103+ beforeLoad : routeConfig . beforeLoad
99104 ? async ( opts : any ) => {
100105 const context : RouteLoaderContext = {
101106 params : opts . params || { } ,
102107 search : opts . search || { } ,
103108 } ;
104- await route . beforeLoad ?. ( context ) ;
109+ await routeConfig . beforeLoad ! ( context ) ;
105110 }
106111 : undefined ,
107- loader : route . loader
112+ loader : routeConfig . loader
108113 ? async ( opts : any ) => {
109114 const context : RouteLoaderContext = {
110115 params : opts . params || { } ,
111116 search : opts . search || { } ,
112117 } ;
113- return await route . loader ?. ( context ) ;
118+ return await routeConfig . loader ! ( context ) ;
114119 }
115120 : undefined ,
116121 component : SurfacesModule ,
@@ -123,22 +128,15 @@ function createRouteFromDefinition( route: Route, parentRoute: AnyRoute ) {
123128 * @param routes Routes definition.
124129 * @return Router tree.
125130 */
126- function createRouteTree ( routes : Route [ ] ) {
131+ async function createRouteTree ( routes : Route [ ] ) {
127132 const rootRoute = createRootRoute ( {
128133 component : Root ,
129134 context : ( ) => ( { } ) ,
130135 } ) ;
131136
132- // Create home route using the route system
133- const homeRouteDefinition : Route = {
134- path : '/' ,
135- content : homeRoute ,
136- } ;
137-
138- // Create routes from definitions including home
139- const allRoutes = [ homeRouteDefinition , ...routes ] ;
140- const dynamicRoutes = allRoutes . map ( ( route ) =>
141- createRouteFromDefinition ( route , rootRoute )
137+ // Create routes from definitions
138+ const dynamicRoutes = await Promise . all (
139+ routes . map ( ( route ) => createRouteFromDefinition ( route , rootRoute ) )
142140 ) ;
143141
144142 return rootRoute . addChildren ( dynamicRoutes ) ;
@@ -166,17 +164,35 @@ interface RouterProps {
166164}
167165
168166export default function Router ( { routes } : RouterProps ) {
169- // Create router with dynamic routes
170- const router = useMemo ( ( ) => {
171- const history = createPathHistory ( ) ;
172- const routeTree = createRouteTree ( routes ) ;
173-
174- return createRouter ( {
175- history,
176- routeTree,
177- defaultNotFoundComponent : NotFoundComponent ,
178- } ) ;
167+ const [ router , setRouter ] = useState < any > ( null ) ;
168+
169+ useEffect ( ( ) => {
170+ let cancelled = false ;
171+
172+ async function initializeRouter ( ) {
173+ const history = createPathHistory ( ) ;
174+ const routeTree = await createRouteTree ( routes ) ;
175+
176+ if ( ! cancelled ) {
177+ const newRouter = createRouter ( {
178+ history,
179+ routeTree,
180+ defaultNotFoundComponent : NotFoundComponent ,
181+ } ) ;
182+ setRouter ( newRouter ) ;
183+ }
184+ }
185+
186+ initializeRouter ( ) ;
187+
188+ return ( ) => {
189+ cancelled = true ;
190+ } ;
179191 } , [ routes ] ) ;
180192
193+ if ( ! router ) {
194+ return < div > Loading routes...</ div > ;
195+ }
196+
181197 return < RouterProvider router = { router } /> ;
182198}
0 commit comments