Ledgee is a 100% client-side, offline-first web application. No server required!
# Build static files
npm run build:static
# Deploy the 'out' folder to any static host!After building, you'll have a out/ folder containing:
out/
├── index.html # Main app entry point
├── _next/
│ ├── static/
│ │ ├── css/ # Stylesheets
│ │ ├── chunks/ # JavaScript bundles
│ │ └── media/ # Assets
├── favicon.svg # App icon
├── sql-wasm.wasm # SQLite WebAssembly
├── manifest.json # PWA manifest
└── 404.html # Error page
Total size: ~500KB (tiny!)
# Install Vercel CLI
npm install -g vercel
# Deploy from project root
vercel
# Follow prompts, done!Why Vercel?
- ✅ Automatic HTTPS
- ✅ Global CDN
- ✅ Perfect for Next.js
- ✅ Free tier available
npm run build:static- Go to netlify.com
- Drag
out/folder to deploy area - Done! Get instant URL
Netlify Features:
- ✅ Instant deployment
- ✅ Form handling (future features)
- ✅ Branch previews
- ✅ Custom domains
# Install gh-pages
npm install -D gh-pages
# Add to package.json scripts:
"deploy:github": "npm run build:static && gh-pages -d out"
# Deploy
npm run deploy:githubAccess: https://yourusername.github.io/shawai
npm run build:static
# Upload 'out' folder to S3 bucket
aws s3 sync out/ s3://your-bucket-name --delete
# Configure CloudFront distribution
# Point to S3 bucket, enable HTTPSnpm run build:static
# Upload 'out' folder contents via FTP/SFTP
# to your web host's public_html folderWorks with: Apache, Nginx, IIS, shared hosting, VPS, etc.
Create .env.local for build-time variables:
# App configuration
NEXT_PUBLIC_APP_NAME=Ledgee
NEXT_PUBLIC_VERSION=1.0.0
# Analytics (optional)
NEXT_PUBLIC_GA_ID=your-google-analytics-id- CNAME Record: Point to your hosting provider
- A Record: Point to hosting IP
- HTTPS: Usually auto-configured by host
For production, ensure your host supports these headers:
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline';
Why needed?
- Required for Chrome LanguageModel API
- Enables advanced browser features
- Improves security
Ledgee is automatically configured as a PWA:
- ✅ Offline caching via Next.js
- ✅ Install prompt on supported browsers
- ✅ App manifest included
- ✅ Service worker auto-generated
# Serve built files locally
npm run serve:static
# Open http://localhost:8080
# Test offline functionality
# Check "Install App" option# Build and serve locally
npm run build:static
npm run serve:static
# Test on http://localhost:8080
# Verify all features work
# Test offline mode (disconnect internet)- LanguageModel API: Requires Chrome Canary with flags
- HTTPS: Some features require secure context
- CORS: Ensure headers are properly set
- Caching: Test offline functionality
- ✅ Code splitting - Only load needed code
- ✅ Tree shaking - Remove unused code
- ✅ Minification - Compressed files
- ✅ Static generation - Pre-built pages
# Cloudflare (free tier)
# - Global CDN
# - DDoS protection
# - Analytics
# AWS CloudFront
# - Integrated with S3
# - Advanced caching rules
# - Custom domains# Clear all caches
npm run clean
npm install
npm run build:static- Check browser console for specific errors
- Verify WASM file is accessible at
/sql-wasm.wasm - Test LanguageModel using debug console in app
- Check localStorage permissions
Production checklist:
- ✅ Using Chrome Canary
- ✅ Flags enabled:
chrome://flags/#prompt-api-for-gemini-nano - ✅ Model downloaded:
chrome://components/ - ✅ HTTPS enabled (for production)
// Add to _app.tsx or layout.tsx
import Script from 'next/script'
export default function RootLayout({ children }) {
return (
<>
<Script
src={`https://www.googletagmanager.com/gtag/js?id=${process.env.NEXT_PUBLIC_GA_ID}`}
strategy="afterInteractive"
/>
<Script id="google-analytics" strategy="afterInteractive">
{`
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '${process.env.NEXT_PUBLIC_GA_ID}');
`}
</Script>
{children}
</>
)
}Consider adding:
- Sentry - Error monitoring
- LogRocket - Session replay
- Hotjar - User behavior analytics
# .github/workflows/deploy.yml
name: Deploy Ledgee
on:
push:
branches: [ main ]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build static files
run: npm run build:static
- name: Deploy to Vercel
uses: amondnet/vercel-action@v20
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }}
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}- ✅ Commit built files? NO - Add
out/to.gitignore - ✅ Use tags for releases:
git tag v1.0.0 - ✅ Semantic versioning
- 🚀 Production:
shawai.com - 🧪 Staging:
staging.shawai.com - 👨💻 Development:
localhost:3000
- ✅ Code: Git repository
- ✅ User data: Exported from localStorage
- ✅ Configuration: Environment variables
Before going live:
- ✅ Build completes without errors
- ✅ All features work in production build
- ✅ HTTPS configured
- ✅ Custom domain set up
- ✅ PWA features tested
- ✅ Chrome LanguageModel working
- ✅ Offline functionality verified
- ✅ Performance optimized
- ✅ Analytics configured
- ✅ Error monitoring set up
- ✅ Backup strategy in place
If deployment fails:
- Check build logs for specific errors
- Test locally with
npm run serve:static - Verify environment variables and configuration
- Review host documentation for static site requirements
Common issues:
- Missing WASM file → Copy
sql-wasm.wasmto output - CORS errors → Configure security headers
- LanguageModel not working → Check Chrome flags
- Routing issues → Ensure trailing slashes configured
🎉 That's it! Ledgee is now deployed as a blazing-fast, offline-first web app with no server required.
Live example: https://your-domain.com
Source: Your static files work anywhere!