Skip to content

Offline Strategy

Macadam ships a service worker (sw.js) that makes the app fully functional without a network connection. Once the user visits the site for the first time while online, every subsequent visit works offline.

macadam-vault-v2

Bump the version suffix when you change any cached asset and want existing users to pick up the update.

On install, the service worker caches:

AssetSource
/, /index.htmlLocal
/weekly.html, /expenses.htmlLocal
/settings.htmlLocal
/static/style.cssLocal
/static/script.jsLocal
/static/db.jsLocal
/static/weekly_vault.jsLocal
/static/expenses_vault.jsLocal
/static/vault_aggregation.jsLocal
/static/vault_backup.jsLocal
/manifest.jsonLocal
Bootstrap CSSCDN
Bootstrap Icons CSSCDN
Bootstrap JS BundleCDN
Dexie.jsCDN

Each asset is cached individually so that a single CDN failure does not prevent the rest from being cached.

Network-first with cache fallback.

  1. Every GET request is sent to the network.
  2. If the response is 200 and basic type, it is cloned into the cache before being returned. This keeps the cache fresh.
  3. If the network fails (offline, timeout), the cached version is served.
  4. Non-GET requests (e.g. POST) bypass the service worker entirely.
  5. Non-HTTP requests (e.g. chrome-extension://) are ignored.
  • Install: skipWaiting() is called so the new worker activates immediately instead of waiting for all tabs to close.
  • Activate: Old caches (any cache name that does not match the current CACHE_NAME) are deleted. clients.claim() is called to take control of open pages immediately.

When you modify any file that the service worker caches:

  1. Change the CACHE_NAME constant in sw.js (e.g. macadam-vault-v3).
  2. Deploy. The browser will detect the byte difference in sw.js and trigger a new install cycle, which pre-caches the updated assets and purges the old cache on activation.

Each HTML page registers the service worker in an inline <script> block at the bottom of <body>:

if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js');
}