The desktop shell is the critical surface of the site. If it hydrates incorrectly, the page can still appear visually present while all meaningful interactions fail.
Failure Pattern
A window app can break the whole shell when all three conditions are true:
- The app is imported statically by the window manager.
- The module does risky work at import time.
- That work depends on content loading or server-only assumptions.
That is what happened with the wildlife photography app. The module was pulled into the shell bundle on startup, reached into content/ directly, and prevented the interactive desktop from finishing hydration.
Required Guardrails
- Load content on the server, not in client shell modules.
- Expose content to apps through Astro routes or precomputed props.
- Lazy-load optional apps so they do not execute during shell bootstrap.
- Wrap each window app in an error boundary.
- Run the client boundary check before shipping.
Current Enforcement
scripts/validate-client-boundaries.mjsnpm run typechecksrc/components/windows/WindowAppBoundary.tsx- lazy imports in
src/components/windows/WindowManager.tsx
Practical Rule
If a feature is experimental, personal, or content-heavy, its failure mode must be local to that window, never global to the shell.