Overview
@saflib/vue provides conventions, components, and workflows for Vue SPAs in SAF products — page structure, reverse-t i18n, TanStack Query integration, product events, and Vitest/Playwright-friendly testing.
Each SPA is one npm package under {product}/clients/{subdomain}/, named after a subdomain (app, auth, admin, …). Subpath-hosted SPAs on another subdomain are not supported. Apex/root clients use a name like root that will not collide with real subdomains.
Use the workflow vue/add-spa to create a new SPA or vue/add-static-site to create a static subdomain with Vitepress, then vue/add-view to add pages to your SPA and vue/add-e2e-test to add Playwright tests.
| Workflow | Use |
|---|---|
| vue/add-spa | New subdomain SPA + build shim + Caddy |
| vue/add-view | New page under an existing SPA |
| vue/add-e2e-test | Playwright spec stub |
| vue/add-static-site | Non-Vue static client |
What this package provides
| Export | Role |
|---|---|
createSpaMain | Standard SPA main() — client name, document title, router, i18n, optional Sentry callback |
createVueApp | Lower-level app bootstrap (Vuetify, Vue Router, TanStack Query, vue-i18n) |
useReverseT / makeReverseTComposable | Value-based i18n lookups — see i18n |
AsyncPage, useAsyncPageDocumentTitle | Code-split pages with loader gating — see Components |
commonEventLogger / makeProductEventLogger | Browser product events → PostHog / dev buffer |
./components | Shared UI (AsyncPage, SpaLink, SnackbarQueue, …) |
./testing | mountWithPlugins, stubGlobals, getElementByString |
./vitest-config | Shared Vitest presets — Coverage enforcement |
./workflows | Scaffold SPAs, views, e2e specs, static sites |
SPA package structure
Golden reference: base/clients/app/.