Documentation
¶
Overview ¶
Package spa demonstrates serving a Vite + React SPA directly from an Envoy dynamic module — no file system access, no separate web server.
Two filters ship in the same .so:
spa — serves embedded ui/dist assets; falls back to index.html for
unmatched paths (SPA client-side routing support)
api-backend — handles /api/* requests directly from Go, no upstream needed
How assets are embedded ¶
The ui/dist directory is embedded at compile time using //go:embed. The Vite build output (index.html + fingerprinted assets/) lives there. For development, run the Vite dev server separately (npm run dev in ui/); for production, run `npm run build` in ui/ then rebuild the .so.
Request routing in Envoy ¶
GET / → spa filter → index.html (200, text/html) GET /assets/*.js → spa filter → fingerprinted asset (200, immutable cache) GET /api/* → api-backend filter → JSON (200, application/json) GET /unknown-page → spa filter → index.html (SPA client-side routing fallback)
All responses are generated inside the filter — no upstream cluster is contacted. The Envoy router is still required at the end of the chain, but the route can point at a blackhole cluster since it is never reached.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var UIFS embed.FS
UIFS holds the compiled Vite output, exported so tests can discover fingerprinted asset filenames at runtime.
Functions ¶
func APIHandler ¶
APIHandler handles /api/* requests and responds directly from the .so. No upstream cluster is contacted — this IS the backend the SPA calls. Exported for unit testing.
Types ¶
This section is empty.