Self-Deploy Your PWA
Fork the template and deploy your own DAO Message instance. All platforms are free. Your messages stay end-to-end encrypted regardless of where you host.
Which Platform?
| Platform | Free Tier | China Access | One-click? |
|---|---|---|---|
| Cloudflare Pages ⭐ | Unlimited bandwidth, 500 builds/mo | 🟢 Best (330+ edges) | ✅ |
| GitHub Pages | Unlimited (public repos) | 🔴 Unstable | ✅ (workflow included) |
| Vercel | 100 GB/mo | 🟡 OK | ✅ |
| Netlify | 100 GB/mo | 🟡 OK | ✅ |
Cloudflare Pages ⭐
Two options — pick one.
Option A · CF Dashboard Git Integration (recommended, no code)
⚠️ Do not use
deploy.workers.cloudflare.com/?url=...— it creates a Worker, not a Pages project, and the build will fail.
Fork the template → github.com/daomessage/securechat-pwa → Fork
Open Cloudflare Pages → dash.cloudflare.com → Create → Pages tab → Connect to Git
Authorize GitHub → select your fork → Begin setup
Build settings (keep defaults):
Field Value Framework preset ViteBuild command npm run buildBuild output directory distNODE_VERSIONenv var22Save and Deploy → ~90 seconds → get
<name>.pages.devNo environment variables needed — the app connects to
relay.daomessage.comautomatically.
Every git push to main auto-deploys from now on. PRs get preview URLs automatically.
Option B · GitHub Actions + Wrangler
If you want CI visibility or want to add test steps before deploy:
Fork the template (same as above)
In Cloudflare Dashboard, create an empty Pages project via Direct Upload (just set a name, skip the upload step)
Add two GitHub Secrets in your fork: Settings → Secrets → Actions
Secret Value CF_ACCOUNT_IDCloudflare Dashboard → right sidebar Account ID CF_API_TOKENAPI Tokens → use "Cloudflare Pages: Edit" template The workflow
.github/workflows/deploy-cloudflare-pages.ymlis already included in the template. Trigger it: Actions tab → Deploy to Cloudflare Pages → Run workflow
Custom Domain (both options)
Pages project → Custom domains → Set up a custom domain → enter chat.yourdomain.com → follow CNAME instructions (auto if domain is on Cloudflare DNS).
GitHub Pages
No third-party account needed — just GitHub.
In your fork: Settings → Pages → Source → "GitHub Actions" (not "Deploy from a branch")
Trigger the first deploy:
- Actions tab → Deploy to GitHub Pages → Run workflow, or
- Push any commit to
main
Visit
https://<your-username>.github.io/securechat-pwa/
The workflow handles the /<repo>/ base path automatically — no code changes needed.
China Access
github.io is frequently blocked or slow in mainland China. Use Cloudflare Pages for China-accessible deployments.
Vercel
Step 1 · Click the button above
Vercel takes you to vercel.com/new/clone and automatically forks the template into your GitHub account.
Step 2 · Sign in to Vercel
Sign in with GitHub (recommended). Vercel will request GitHub authorization.
Step 3 · Configure the project
| Field | Value |
|---|---|
| Project Name | Change to your preferred name (becomes <name>.vercel.app) |
| Framework Preset | Auto-detected as Vite — leave as-is |
| Build Command | npm run build (pre-filled) |
| Output Directory | dist (pre-filled) |
No environment variables needed.
Step 4 · Click Deploy
~60 seconds. When done, click <name>.vercel.app to open your app.
Auto-deploy: Every push to main in your forked repo triggers a rebuild automatically.
Custom domain: Project dashboard → Settings → Domains → enter your domain → follow CNAME instructions.
Netlify
Step 1 · Click the button above
Netlify takes you to app.netlify.com/start/deploy and automatically forks the template into your GitHub account.
Step 2 · Sign in to Netlify
Sign in with GitHub (recommended). Netlify will request GitHub authorization.
Step 3 · Name your repository
Netlify asks what to name the forked repo. Default is securechat-pwa — change if you like.
Step 4 · Click Save & Deploy
~90 seconds. When done, click the <random-name>.netlify.app link to open your app.
Build config (build command = npm run build, publish directory = dist) is provided automatically by netlify.toml in the repo — nothing to fill in manually.
Auto-deploy: Every push to main triggers a rebuild. PRs get automatic preview URLs.
Custom domain: Site dashboard → Domain settings → Add custom domain → enter domain → configure DNS as instructed.
Troubleshooting
Build fails — "npm ci EUSAGE" or lock file mismatch Sync your fork with upstream: your fork on GitHub → Sync fork → Update branch → redeploy.
CORS error on login/register The relay's CORS policy is fully open as of 2026-04-21. If you still see this: clear browser cache and reload.
Refresh on sub-routes returns 404
- Cloudflare Pages: handled by
public/_redirects(already included) - GitHub Pages: handled by
404.htmltrick (the workflow copiesindex.html → 404.htmlautomatically) - Vercel/Netlify: handled by their built-in SPA rewrite
iOS Safari — notifications don't work Web Push on iOS requires the PWA to be added to home screen first (Safari → Share → Add to Home Screen). The app shows an install prompt automatically.
How do I update to the latest template version? Your fork on GitHub → Sync fork → Update branch. Your hosting platform rebuilds automatically.