0015: Contextual Shell Chrome Strategy
Date: 2025-08-11
Status: Revised
Context
The Citadel shell-app must host a diverse range of Micro-Frontends (MFEs). The original strategy assumed the shell would provide a standard UI chrome (header, navigation sidebar). However, as defined in ADR-0003, the shell's role has been redefined to be extremely minimalist. It is responsible only for core identity and context management (login, logout, user/tenant switching) and must not impose any application-level layout or navigation on the MFEs it hosts.
A static, rigid shell layout would violate this principle and compromise the UX of hosted applications. We need a strategy that ensures the shell's UI is minimal and non-intrusive by default.
Decision
We will implement a "Minimalist Chrome" strategy for the shell application. The shell will not have a "standard view" or an opt-in "focus mode"; it will be in a minimalist state by default.
-
Minimal Chrome by Default: The
shell-appwill render only a minimal, non-intrusive UI element. This "chrome" is strictly limited to functions related to identity and context management:- Displaying the current user and tenant.
- Providing actions for
logout,user-switching, andtenant-switching.
-
No Application Navigation: The shell will not provide any application-level navigation elements like a sidebar, header, or main menu. Each hosted MFE is entirely responsible for its own layout and navigation.
-
Unobtrusive Positioning: The minimal chrome (e.g., a small user profile dropdown) will be rendered in a fixed, unobtrusive corner of the viewport (e.g., top-right) to avoid interfering with the MFE's content.
-
Optional "Chrome-less" Mode: For MFEs that require complete control over the UI, they can opt-out of the minimal chrome entirely.
- This will be achieved via a declarative flag in the MFE's route configuration (e.g.,
data: { chrome: 'none' }). - When this flag is detected, the shell will not render any UI elements, yielding the entire viewport to the MFE.
- The shell must provide a programmatic API (e.g., a JavaScript SDK or a
postMessageinterface) to allow the "chrome-less" MFE to trigger core actions likelogout.
- This will be achieved via a declarative flag in the MFE's route configuration (e.g.,
Consequences
Positive
- Maximum Flexibility for MFEs: MFE developers have complete control over their application's layout and user experience, without interference from the shell.
- Clear Separation of Concerns: The shell is responsible for identity; MFEs are responsible for application functionality. This boundary is clean and unambiguous.
- Simplified Shell Logic: The shell's layout logic is drastically simplified, as it no longer needs to manage multiple states (e.g., "standard" vs. "focus").
Negative
- Potential for Inconsistent UX: Without a shared shell navigation, maintaining a consistent user experience across different MFEs requires strong design system governance and shared component libraries that MFEs must adopt.
- Increased MFE Responsibility: Each MFE must implement its own navigation. If an MFE opts for the "chrome-less" mode, it also becomes responsible for providing UI for critical identity functions like logout, which it must trigger via the shell's programmatic API. This is an accepted trade-off for ultimate flexibility.
- Added API Contract: The need for a programmatic API for "chrome-less" MFEs adds a new, formal contract that the shell must maintain, increasing its surface area slightly.