HTML Tutorial 0/139 lessons ~6 min read Lesson 126

    Micro-Frontends Document Shell

    micro-frontends document shell micro-frontend architecture lives or dies on the document shell: unified head po micro-frontends split a product across

    Course progress0%
    Focus
    18 guided sections
    Practice signal
    Examples included
    Career prep
    Interview Q&A included

    Introduction

    Micro-frontends split a product across autonomous teams, each shipping UI to a shared document shell — the single HTML document owning <head>, global nav, CSP, and mount points for remotes. Shell HTML quality determines SEO, security, and whether users perceive one product or a franken-page.

    Business problem

    Business pressure: Enterprise acquisitions integrate three codebases on one domain. Without a shell contract, each team injects duplicate GTM snippets, conflicting meta tags, and incompatible design tokens — brand trust erodes and SEO duplicates explode.

    • Velocity: Teams deploy independently — shell must version mount points and shared assets safely.
    • SEO: One canonical, one title policy — remotes cannot each emit full documents.
    • Security: Single CSP and SRI policy at shell — remotes run inside trust boundaries.

    Why this feature exists

    Platform motivation: Monolith frontends bottleneck 20 teams. Micro-frontends trade integration complexity for autonomy. The shell exists because browsers have one document — you cannot merge three <html> tags.

    • History: iframes (Amazon), module federation (Webpack 5), single-spa, import maps, web components.
    • Alternative rejected: Separate subdomains per team — breaks unified checkout and cookie session.
    • Modern role: Shell as platform product; remotes as consumers of HTML slots and event bus.

    Browser internals

    Inside the engine: Shell HTML loads first. Parser builds DOM with empty mount nodes. Remote scripts (federation or custom elements) fetch asynchronously and attach subtrees — layout recalc when remotes paint can cause CLS if shell lacks skeleton dimensions.

    • Script order: Shell defines import map / remoteEntry; remotes must not document.write.
    • CSS: Global tokens in shell; remote CSS may FOUC — shadow DOM or strict naming conventions.
    • Focus: Cross-remote focus management is shell responsibility for a11y.

    Rendering workflow

    Rendering path: Edge serves shell HTML with SSR optional for shell nav. Remotes hydrate client-side or SSR fragments injected server-side (composition layer). Composition at edge (ESI, workers) vs client (federation) affects TTFB and cache.

    • Client composition: Faster shell TTFB; CLS risk when remotes load.
    • Server composition: Heavier origin; better first paint coherence.
    • Navigation: Shell router vs remote routers — must not fight History API.

    Feature deep dive

    Shell contract — slots, shared dependencies, event API, and forbidden head mutations. Document in HTML comments or meta for tooling.

    • Slots: <div id="mfe-checkout"> with min-height skeleton.
    • Shared libs: React singleton via federation shared scope — version pinned in shell.
    • Events: CustomEvent bus on window — decouple remotes without importing each other.
    html
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Acme — Shell</title>
    <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' https://cdn.acme.com">
    <link rel="stylesheet" href="https://cdn.acme.com/shell/design-system.css">
    </head>
    <body>
    <header id="shell-nav"><!-- shell team --></header>
    <main>
    <div id="mfe-catalog" data-min-height="480"><!-- remote A --></div>
    <div id="mfe-cart" data-min-height="120"><!-- remote B --></div>
    </main>
    <script type="importmap">{"imports":{"react":"https://cdn.acme.com/react@18.3.1"}}</script>
    <script type="module" src="https://cdn.acme.com/shell/bootstrap.js"></script>
    </body>
    </html>

    Accessibility analysis

    A11y architecture: One <main>, one skip link, logical heading order across remotes — enforced by shell lint. Remotes must not emit landmark roles that duplicate shell landmarks.

    • Heading hierarchy: Shell owns h1 policy per route — remotes start at h2.
    • Focus: Shell announces route changes; remotes register with focus registry.

    SEO impact

    SEO architecture: Shell sets canonical, hreflang, and robots. Remotes supply fragment HTML for main content — composition service merges before crawl. Client-only remote mount fails SEO for public routes.

    • SSR merge: Server includes remote HTML for Tier-0 URLs in shell main slot.
    • Title: Shell template + remote meta fragment — single title element.

    Security considerations

    Security boundary: Remotes are semi-trusted. CSP at shell restricts script origins. Avoid remotes injecting inline script — use nonce from shell SSR.

    • CSP nonce: Generated per request in shell — passed to trusted remotes only.
    • iframe sandbox: Untrusted third-party MFE in sandboxed iframe with postMessage API.

    Performance impact

    Performance: Sequential remote loading hurts LCP — parallelize with modulepreload for remoteEntry. Reserve slot heights in shell HTML to prevent CLS.

    • LCP: LCP element often in catalog remote — preload its critical CSS in shell head.
    • INP: Multiple React roots — avoid duplicate scheduler work; shared runtime.

    Real production example

    Production pattern: Zalando-style shell with server-side fragment inclusion for PLP HTML; checkout remote federated client-side behind auth. Shell CI validates merged HTML with axe and canonical uniqueness.

    • Composition service: Node worker fetches remote SSR fragments with timeout fallback skeleton.
    • Deploy: Shell daily; remotes hourly — compatibility matrix in registry.

    Enterprise usage

    Enterprise: Platform team owns shell repo, design tokens, CSP, and MFE registry. Product teams register mount points and semver contracts.

    • ADR: Required for new remote — SEO tier, auth, and data classification.
    • Observability: Shell RUM tags remote version on each slot via data attributes.

    Common production failures

    What breaks in prod: Remote deploy breaks shared React version — white screen. Two remotes set document.title — SEO chaos. Missing skeleton height — CLS 0.35 on mobile.

    • Incident: Federation shared dependency mismatch — rollback remote only; shell pins versions afterward.
    • SEO: Client-only catalog remote — Google indexed shell nav only; added SSR fragment merge.

    Architecture review questions

    • Who owns head tags, CSP, and canonical for this route?
    • Is Tier-0 content present in merged server HTML?
    • What happens when a remote fails to load — fallback HTML?
    • How are shared library versions pinned and tested?
    • Is there exactly one main landmark and one h1?

    Hands-on project

    Project: Build minimal shell with two mount points and mock remotes (web components). Add CSP, skeleton min-heights, and merged HTML snapshot test.

    • Deliverable: shell.html, two remote scripts, composition diagram.

    Interview questions

    How do micro-frontends affect SEO and what mitigations do you use?(Advanced)

    Public routes need server-composed HTML in shell main — not client-only mounts. Shell owns canonical and structured data merge. Use SSR fragments or edge includes for Tier-0 content.

    Follow-up: When is iframe-based MFE acceptable?

    Try it yourself

    Edit the HTML, CSS, or JS panels — the preview updates as you type.

    Try it yourself

    Preview

    Summary

    Micro-frontend architecture lives or dies on the document shell: unified head policy, accessible landmarks, CSP, and server composition for SEO routes. Platform teams treat the shell as a product with contracts, not a throwaway wrapper.

    Ready to mark this lesson complete?Track your journey across the entire course.