The short answer
For an application that needs both search-engine visibility and offline access, SSR is the non-negotiable half — but the premise that you must pick one mode is false. In Quasar, SSR and PWA are not mutually exclusive: you can add PWA support on top of an SSR build, so the server renders indexable HTML and a service worker caches it for offline use. The sustainable architecture is SSR-first with a carefully scoped service worker, not PWA-instead-of-SSR.
Why SSR wins the SEO half
Search crawlers can execute JavaScript, but rendering is deferred, sometimes fails, and is unreliable for content that must be indexed on day one. SSR delivers complete HTML in the initial response, so titles, meta tags, structured data, and body content are visible in view-source: without any script execution. A pure PWA (SPA mode plus a service worker) ships an empty shell that only fills in after hydration — fine for apps behind a login, risky for anything whose rankings pay the bills.
Why PWA alone can't replace it
A service worker only helps returning visitors. It registers after the first load, so it does nothing for the first paint, and it does nothing for a crawler. Prioritizing PWA caching over SSR means every first visit — including every bot visit — depends on client-side rendering. That trades your SEO guarantee for an offline feature only existing users experience.
The combined setup
Assuming Quasar v2 (Vue 3):
quasar mode add ssr
quasar mode add pwa
In quasar.config.js, build for SSR and configure the PWA section (workbox options, manifest). Quasar injects the service worker into the SSR build, so the flow becomes:
- Server renders full HTML → crawler and first-time user see content immediately.
- Client hydrates and registers the service worker.
- Service worker precaches the app shell and caches navigations/API responses per your strategy, enabling offline reloads.
The real risk: hydration vs. cache conflicts
The concern you raised about testing hydration against service-worker caching is the correct thing to worry about. The classic failure is a CacheFirst strategy on HTML navigations serving a stale shell that mismatches the server's current payload, causing hydration errors or outdated content. Mitigations:
- Use
NetworkFirst (with an offline fallback page) for HTML navigations; reserve CacheFirst for hashed static assets.
- Never cache authenticated or personalized responses without explicit cache keys per user — or exclude them entirely.
- Version your precache so deployments trigger service worker updates cleanly.
Verifying without production credentials
You can validate everything locally:
- SSR correctness: run
quasar build -m ssr, serve it, then curl -s http://localhost:3000/some-route | grep "expected content". If the content is in the raw HTML, crawlers will see it.
- Offline behavior: in Chrome DevTools → Application → Service Workers, confirm registration; then check the "Offline" box in the Network tab and reload. Cached routes should render; uncached ones should hit your fallback.
- Cache contents: Application → Cache Storage shows exactly what the workbox strategy stored — confirm no session-specific data is present.
Bottom line
SSR is the sustainable choice for SEO; PWA is an add-on, not an alternative. Run both modes together, keep HTML caching conservative, and verify with curl plus DevTools' offline toggle before you ever need production credentials.