Layer routing in @esmx/router provides a mechanism for creating isolated routing contexts that overlay the main application. Layers are commonly used for modal dialogs, wizards, or any UI that needs its own navigation stack while visually overlaying the main content.
interface RouteLayerOptions {
zIndex?: number;
keepAlive?: 'exact' | 'include' | RouteVerifyHook;
shouldClose?: RouteVerifyHook;
autoPush?: boolean;
push?: boolean;
routerOptions?: RouterLayerOptions;
}Configuration options for layer creation:
numberCustom z-index value for the layer. If not set, uses the base z-index (10000) plus an auto-incremented value.
'exact' | 'include' | RouteVerifyHook'exact'Controls when the layer remains open during navigation:
'exact': Keep layer alive only when navigating to the exact initial path (default)'include': Keep layer alive when navigating to paths that start with the initial pathfunction: Custom logic returning true to keep alive, false to close// Default - keep only on exact path match
keepAlive: 'exact'
// Keep alive on any sub-path
keepAlive: 'include'
// Custom logic
keepAlive: (to, from, router) => {
return to.query.keepLayer === 'true';
}booleantrueWhether to automatically push the layer's exit route to the parent router when the layer closes due to a navigation push.
booleantrueWhether to record a history entry for the layer opening. When true, pressing the browser back button will close the layer.
RouterLayerOptionsAdditional router options for the layer's internal router instance. Merged with the parent router's configuration.
type RouterLayerOptions = Omit<
RouterOptions,
'handleBackBoundary' | 'handleLayerClose' | 'layer'
>;Router options for layer creation. Same as RouterOptions but excludes handler functions and the layer flag which are managed internally.
type RouteLayerResult =
| { type: 'close'; route: Route }
| { type: 'push'; route: Route }
| { type: 'success'; route: Route; data?: any };Result returned when a layer closes:
close: Layer was closed via router.closeLayer() without data, or by navigating backpush: Layer was closed because navigation exited the layer's scopesuccess: Layer was closed via router.closeLayer(data) with datatoInput: RouteLocationInput — Target route for the layerPromise<{ promise: Promise<RouteLayerResult>; router: Router }>Creates a layer routing instance. Returns both the layer's router and a promise that resolves when the layer closes.
const { promise, router: layerRouter } = await router.createLayer({
path: '/select-user',
layer: {
keepAlive: 'include',
autoPush: true,
push: true
}
});
// Wait for layer to close
const result = await promise;
switch (result.type) {
case 'success':
console.log('User selected:', result.data);
break;
case 'close':
console.log('Layer dismissed');
break;
case 'push':
console.log('Navigation left layer');
break;
}toInput: RouteLocationInput — Target route locationPromise<RouteLayerResult>Shorthand for creating a layer and waiting for its result. Navigates to the route as a layer.
const result = await router.pushLayer({
path: '/confirm-action',
layer: {
keepAlive: 'exact'
}
});
if (result.type === 'success') {
// User confirmed
performAction(result.data);
}data?: any — Optional data to return to the parentvoidCloses the current layer. Only effective when the router is a layer instance (router.isLayer === true).
// Close without data (result.type === 'close')
router.closeLayer();
// Close with data (result.type === 'success')
router.closeLayer({ selectedId: 42, confirmed: true });createLayer() or pushLayer() creates a new Router instance in memory modecloseLayer() is calledkeepAlive scopedestroy() is called automatically, removing the DOM element and cleaning up resources// Parent component - open a selection dialog
async function selectUser() {
const result = await router.pushLayer({
path: '/users/select',
layer: {
keepAlive: 'include', // Allow navigation within /users/*
autoPush: true, // Auto-push exit route
push: true, // Add browser history entry
routerOptions: {
routes: dialogRoutes // Custom routes for the layer
}
}
});
if (result.type === 'success') {
setSelectedUser(result.data);
}
}
// Inside the layer component
function onUserSelected(user: User) {
// Close layer and return selected user
router.closeLayer(user);
}
function onCancel() {
// Close layer without data
router.closeLayer();
}