logo
  • Guide
  • API
  • Blog
  • English
    • 简体中文
    • English
    • @esmx/core
      Esmx
      App
      RenderContext
      ModuleConfig
      PackConfig
      ManifestJson
      @esmx/router
      Router
      Route
      Route Configuration
      RouterLink
      Navigation Guards
      Dynamic Route Matching
      Nested Routes
      Programmatic Navigation
      Scroll Behavior
      Layer Routing
      MicroApp
      Error Types
      Types Reference
      @esmx/router-vue
      RouterPlugin
      Composables
      Components
      Type Augmentation
      @esmx/router-react
      Micro-App Integration
      Hooks & Context
      Components
      SSR
      App
      @esmx/rspack
      @esmx/rspack-vue
      @esmx/rspack-react

      Last Updated: 4/7/2026, 2:16:07 AM

      Previous pageScroll BehaviorNext pageMicroApp

      #Layer Routing

      #Introduction

      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.

      #Type Definitions

      #RouteLayerOptions

      • Type Definition:
      interface RouteLayerOptions {
          zIndex?: number;
          keepAlive?: 'exact' | 'include' | RouteVerifyHook;
          shouldClose?: RouteVerifyHook;
          autoPush?: boolean;
          push?: boolean;
          routerOptions?: RouterLayerOptions;
      }

      Configuration options for layer creation:

      #zIndex

      • Type: number

      Custom z-index value for the layer. If not set, uses the base z-index (10000) plus an auto-incremented value.

      #keepAlive

      • Type: 'exact' | 'include' | RouteVerifyHook
      • Default: '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 path
      • function: 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';
      }

      #autoPush

      • Type: boolean
      • Default: true

      Whether to automatically push the layer's exit route to the parent router when the layer closes due to a navigation push.

      #push

      • Type: boolean
      • Default: true

      Whether to record a history entry for the layer opening. When true, pressing the browser back button will close the layer.

      #routerOptions

      • Type: RouterLayerOptions

      Additional router options for the layer's internal router instance. Merged with the parent router's configuration.

      #RouterLayerOptions

      • Type Definition:
      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.

      #RouteLayerResult

      • Type Definition:
      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 back
      • push: Layer was closed because navigation exited the layer's scope
      • success: Layer was closed via router.closeLayer(data) with data

      #Methods

      #router.createLayer()

      • Parameters:
        • toInput: RouteLocationInput — Target route for the layer
      • Returns: Promise<{ 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;
      }

      #router.pushLayer()

      • Parameters:
        • toInput: RouteLocationInput — Target route location
      • Returns: Promise<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);
      }

      #router.closeLayer()

      • Parameters:
        • data?: any — Optional data to return to the parent
      • Returns: void

      Closes 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 });

      #Layer Lifecycle

      1. Creation: createLayer() or pushLayer() creates a new Router instance in memory mode
      2. Mounting: The layer's root element is appended to the document body with overlay styling
      3. Navigation: The layer has its own isolated navigation stack
      4. Closing: The layer closes when:
        • closeLayer() is called
        • The user navigates back with no history left
        • Navigation exits the layer's keepAlive scope
      5. Cleanup: destroy() is called automatically, removing the DOM element and cleaning up resources

      #Complete Example

      // 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();
      }