Client PWA Deployment
The client is an offline-first Progressive Web App built with Vite and React. Deployment produces a static build with service worker support for offline functionality.

Deployment Checklist
- Ensure
packages/contractsandpackages/sharedare built (the client depends on both) - Set the correct
VITE_CHAIN_IDfor the target environment in the root.env - Verify all required environment variables are configured (see Build Environments)
- Build the client:
VITE_CHAIN_ID=42161 bun run build:client - Deploy static output from
packages/client/dist/to your CDN or static hosting provider - Configure cache-busting headers for
index.htmland long-lived caching for hashed static assets - Verify the service worker registers and precaches assets correctly
- Run Lighthouse audit to check Performance, Accessibility, PWA readiness, and SEO
Build Environments
Build Dependencies
The client depends on packages built earlier in the dependency chain:
packages/contracts-- ABI JSON files and deployment artifactspackages/shared-- React hooks, modules, types, and components
Both must be built before the client. The monorepo's bun build command handles this order automatically.
Environment Variables
All environment variables come from the root .env file (never package-specific). Key variables for the client build:
| Variable | Purpose |
|---|---|
VITE_CHAIN_ID | Target chain (e.g., 11155111 for Sepolia, 42161 for Arbitrum) |
VITE_WALLETCONNECT_PROJECT_ID | WalletConnect authentication |
VITE_PIMLICO_API_KEY | Pimlico bundler/paymaster for account abstraction |
VITE_ENVIO_INDEXER_URL | Envio GraphQL endpoint |
Single-Chain Build
The build is single-chain: VITE_CHAIN_ID determines which deployment artifact and chain configuration is baked in at build time.
Making A Deployment
Build Process
# Build for production
VITE_CHAIN_ID=42161 bun run build:client
Static Hosting
The client build outputs to packages/client/dist/. This is a fully static site deployable to any CDN or static hosting provider.
CI Build
The E2E workflow builds the client with test configuration:
- name: Build client for E2E
run: bun run build:client
env:
VITE_USE_HASH_ROUTER: "true"
VITE_CHAIN_ID: "11155111"
VITE_USE_HASH_ROUTER enables hash-based routing for environments where server-side routing is not available (e.g., IPFS hosting).
Service Worker
The PWA service worker enables offline functionality -- the core differentiator of the client app. Key behaviors:
- Precaching -- Static assets are cached at install time
- Runtime caching -- API responses are cached with stale-while-revalidate
- Background sync -- Work submissions queue when offline and sync when connectivity returns
- Update detection -- The
useServiceWorkerUpdatehook detects new versions and prompts users
Service Worker Update Flow
The shared hook useServiceWorkerUpdate handles the update lifecycle:
- Detect waiting service worker
- Show update prompt to user
- On accept, send
SKIP_WAITINGmessage - Reload the page with the new version
Offline-First Architecture
The client is designed to work without internet connectivity:
- IndexedDB stores drafts, work submissions, and cached garden data via the job queue system
- Draft auto-save persists form state every few seconds
- Background sync processes queued mutations when connectivity returns
- Optimistic updates show pending changes immediately in the UI
This architecture means the deployment must ensure the service worker and precached assets are delivered correctly. Cache-busting headers should be set for index.html but long-lived caching for hashed static assets.
Performance Monitoring
The lighthouse-ci.yml workflow runs Lighthouse audits against deployed sites, checking:
- Performance score
- Accessibility compliance
- PWA readiness
- SEO basics
Source maps are uploaded separately via upload-sourcemaps.yml for error tracking in production.
Resources
Next: Deploy the Admin Dashboard
The admin dashboard shares the same build toolchain as the client but targets garden operators with role-based access.
Admin Dashboard Deployment