Chuyển đến nội dung chính

Lesson 13: Shell Application — Routing, Layout & Orchestration

Shell Application design: Global Layout, Routing orchestration, Authentication integration, Version management, Performance budget.

🏗️ Architecture — Lesson 13 Lesson 13: Shell Application — Routing, Layout & Orchestration

Microservices & Micro Frontend system design — From basics to Production

Part 5: Building a practical Micro Frontend

xdev.asia

Introduction

Shell Application (Container App) is the coordinating brain of the entire Micro Frontend. It determines layout, routing, authentication, and how MFEs communicate with each other.

Shell Application — orchestrator for Micro Frontends


1. Shell Application Responsibilities

Shell Application:
├── Layout Management (Header, Footer, Sidebar)
├── Routing Orchestration (top-level routes → MFE)
├── Authentication (Login/Logout, token management)
├── Shared Services (Event Bus, Error Boundary)
└── Performance (Lazy loading, prefetching)

2. Routing Architecture

2.1 Route Ownership

Each MFE owns its routes, the shell only delegates:

function ShellRoutes() {
  return (
    <Routes>
      <Route path="/" element={<HomePage />} />
      <Route path="/products/*" element={
        <MFELoader name="product" module="./ProductRoutes" />
      } />
      <Route path="/cart/*" element={
        <MFELoader name="cart" module="./CartRoutes" />
      } />
      <Route path="/orders/*" element={
        <MFELoader name="order" module="./OrderRoutes" />
      } />
      <Route path="*" element={<NotFound />} />
    </Routes>
  );
}

2.2 MFE Internal Routes

// Product MFE - own routes
function ProductRoutes() {
  return (
    <Routes>
      <Route index element={<ProductList />} />
      <Route path=":id" element={<ProductDetail />} />
      <Route path="category/:slug" element={<CategoryPage />} />
    </Routes>
  );
}

3. Layout Architecture

┌─────────────────────────────────────────────┐
│ Shell App                                   │
│ ┌─────────────────────────────────────────┐ │
│ │ Header (Shell-owned)                    │ │
│ │ Logo │ Nav │ Search │ Cart │ User │     │ │
│ ├─────┬───────────────────────────────────┤ │
│ │Side │  ┌─────────────────────────────┐  │ │
│ │bar  │  │  MFE Content Area           │  │ │
│ │     │  │  (dynamic, loaded by route) │  │ │
│ │     │  └─────────────────────────────┘  │ │
│ ├─────┴───────────────────────────────────┤ │
│ │ Footer (Shell-owned)                    │ │
│ └─────────────────────────────────────────┘ │
└─────────────────────────────────────────────┘

Shell management: Header, Footer, Sidebar, Loading, Error boundaries MFE manages: Content area, Internal routing, Local state


4. Authentication Integration

Shell handles login → broadcasts auth state to MFEs:

Shell App ──login──► Keycloak (OIDC)
Shell App ◄──tokens── Keycloak
Shell App ═══broadcast══► MFE A (useAuth())
Shell App ═══broadcast══► MFE B (useAuth())
function Shell() {
  const auth = useKeycloakAuth();
  return (
    <AuthContext.Provider value={auth}>
      <Header user={auth.user} />
      <Suspense fallback={<Loading />}>
        <Outlet />
      </Suspense>
    </AuthContext.Provider>
  );
}

5. Performance Strategies

5.1 Lazy Loading + Prefetch

function NavLink({ to, mfeName, children }) {
  const handleMouseEnter = () => {
    import(/* webpackPrefetch: true */ `${mfeName}/Routes`);
  };
  return <Link to={to} onMouseEnter={handleMouseEnter}>{children}</Link>;
}

5.2 Performance Budget

Per MFE limits:
├── JavaScript: max 250KB gzipped
├── CSS: max 50KB gzipped
├── First Contentful Paint: < 1.5s
├── Time to Interactive: < 3s
└── Lighthouse Score: > 80

Summary

  • Shell = orchestrator — owns layout, routing, auth
  • Each MFE owns content area and internal routes
  • Auth handled by Shell, broadcast to MFEs
  • Shell must be thin — does not contain business logic

Next article: Lesson 14: Cross-MFE State Management & Communication