Skip to main content

SPA Guard

A family of packages for resilient single-page applications with automatic retry, cache busting, and error reporting.

What is SPA Guard?​

SPA Guard handles the "white screen of death" that occurs when your SPA's JavaScript chunks fail to load — whether from network issues, deployment cache invalidation, CDN problems, or static asset 404s. It automatically retries loading, shows user-friendly fallback UI, and reports errors via beacons.

Package Family​

The spa-guard functionality is split into 7 separate packages, each with a focused responsibility:

PackageDescriptionPeer Dependencies
@ovineko/spa-guardCore runtime, error handling, schema, i18nNone
@ovineko/spa-guard-reactReact hooks, components, error boundariesreact@^19
@ovineko/spa-guard-react-routerReact Router v7 error boundary integrationreact@^19, react-router@^7
@ovineko/spa-guard-viteVite plugin (injects runtime script at build time)vite@^8||^7
@ovineko/spa-guard-nodeServer-side HTML cache with ETag/304, pre-compression, i18nparse5@^8
@ovineko/spa-guard-fastifyFastify beacon endpoint plugin and HTML cache handlerfastify@^5||^4
@ovineko/spa-guard-eslintESLint rules for enforcing spa-guard patternseslint@^9||^10

Architecture​

Configuration flows from the Vite plugin at build time into the runtime:

Two-Level Retry Strategy​

  1. Module-level retry (lazyWithRetry in spa-guard-react): Retries the individual import() call with configurable delays before the component fails.
  2. Page-level retry (retryOrchestrator in core): If module retry fails, schedules a full page reload with cache busting.

Retry State Machine​

The orchestrator maintains an explicit phase:

  • idle — no retry in progress
  • scheduled — a reload has been scheduled; concurrent triggers are deduplicated
  • fallback — retries exhausted, fallback UI is shown; further triggers are ignored

Quick Start​

1. Install packages​

pnpm add @ovineko/spa-guard @ovineko/spa-guard-react
pnpm add -D @ovineko/spa-guard-vite

2. Add the Vite plugin​

import { spaGuardVitePlugin } from "@ovineko/spa-guard-vite";
import { defineConfig } from "vite";

export default defineConfig({
plugins: [spaGuardVitePlugin()],
});

3. Use lazyWithRetry in your React app​

import { Suspense } from "react";
import { lazyWithRetry } from "@ovineko/spa-guard-react";

const LazyHome = lazyWithRetry(() => import("./pages/Home"));

export function App() {
return (
<Suspense fallback={<div>Loading...</div>}>
<LazyHome />
</Suspense>
);
}

4. Call recommendedSetup​

import { recommendedSetup } from "@ovineko/spa-guard/runtime";

const cleanup = recommendedSetup();

See individual package pages for detailed API documentation and configuration options.