The GenericPageModule is a Module Federation remote responsible for integrating a generic page into the host application.
It provides a standard page composition model based on:
- a layout module
- a page module
- a route definition
- a lifecycle hook
The module is implemented as a BasicRemoteModule<ModulePageOptions> and exposes the following responsibilities:
- Register the module in the host system
- Contribute a navigation entry in the main menu
- Provide a federated route configuration
- Resolve layout and page components via Module Federation
During postInit, the module registers itself into the host navigation menu using the configured basePath and localized label.
No additional lifecycle behavior is required beyond this registration step.
The module exposes a federated route structure built from two different levels of the host configuration:
| Key | Location | Role |
|---|---|---|
basePath |
module configuration root | Root route the module is mounted at |
pagePath |
options |
Internal page route, nested under basePath |
layout |
options |
Layout component resolved via Module Federation |
page |
options |
Page component resolved via Module Federation |
This results in a nested route structure:
basePath/
└── pagePath → page rendered inside layout
parentPath is not part of this structure: it is not a mount point but a navigation target,
read by the page itself when the user cancels or goes back.
Path:
./PageRoutesPurpose: Exposes the route definition used by the host router to mount the page module.
Path:
./PageLifecyclePurpose:
Handles module initialization lifecycle logic (postInit, registration, etc.).
Some components are registered automatically, without any configuration in the module file.
| Zone | Component | Registered by |
|---|---|---|
base-layout.dialogComponent |
LinPulsar/ConfirmationDialog |
LinPulsar/PageLifecycle (init) |
base-layout.dialogComponent |
LinPulsar/FormDialog |
LinPulsar/PageLifecycle (init) |
Both dialogs are registered with registerPluginOnce, so they are mounted a single time even when several module
instances use LinPulsar/PageLifecycle. This is what allows any component of a generic page to open a confirmation
or a form dialog through the uiEventSubject bus, without declaring anything.
The module is configured using ModulePageOptions:
interface ModulePageOptions extends ModulePageLifecycleHostOptions {
layout: string; // MF remote/component for layout
page: string; // MF remote/component for page
parentPath: string; // route to return to, e.g. on cancel
pagePath: string; // route path inside the module
}
// from @linagora/lin-pulsar-core
interface ModulePageLifecycleHostOptions {
addNavigationMenu?: boolean; // default false
}parentPath supports Nunjucks template interpolation with two variables, so the path can be built
from the current context instead of being hardcoded. Generic pages render it when the user cancels
or navigates back.
| Variable | Content |
|---|---|
entity |
Current entity state of the page ({} when none is loaded) |
query |
Query string of the current page (route.query) |
Prefer query for the segments identifying the parent route — "/groups/{{ query.groupId }}/members".
A generic page route is basePath + pagePath and declares no parent segment, so route.params
holds nothing usable for one: the query string is where such an identifier travels. entity is
empty on a creation page until the form is filled, and on a details page whose entity failed to
load.
These options are the shared baseline. Each generic page extends ModulePageOptions with
its own type — ModuleGenericCreationPageOptions, ModuleGenericDetailsPageOptions, and so
on — adding page-specific options on top. See Generic Pages for the
per-page contracts.
- Module is initialized via
BasicRemoteModule postInitregisters navigation entry only ifaddNavigationMenuis set to true.- Routes are exposed via
PageRoutes - Lifecycle logic is exposed via
PageLifecycle - Page is rendered using federated layout + page components
This module is intended as a generic reusable page container. All domain-specific logic must be implemented in the federated page or layout modules.