Skip to main content

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.

  1. Minimal Chrome by Default: The shell-app will 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, and tenant-switching.
  2. 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.

  3. 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.

  4. 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 postMessage interface) to allow the "chrome-less" MFE to trigger core actions like logout.

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.