Complete guide to deploying Broadcast to Netlify.
Before deploying:
- ✅ GitHub account
- ✅ Netlify account (free tier is fine)
- ✅ Supabase project set up
- ✅ Stripe account configured
- ✅ Platform API keys ready
- Create a new GitHub repository:
# Initialize git if not already done
git init
# Add all files
git add .
# Commit
git commit -m "Initial commit - Broadcast app"
# Add remote (replace with your repo URL)
git remote add origin https://github.com/yourusername/broadcast.git
# Push to GitHub
git push -u origin main- Make sure
.envis in.gitignore:
# Already in .gitignore, but verify:
echo ".env" >> .gitignore
echo ".env.local" >> .gitignore
echo ".env.production" >> .gitignore- Go to app.netlify.com
- Click "Add new site" → "Import an existing project"
- Choose "Deploy with GitHub"
- Authorize Netlify to access your repositories
- Select your
broadcastrepository - Configure build settings:
- Build command:
npm run build - Publish directory:
.output/public - Functions directory:
.output/server
- Build command:
- Click "Deploy site"
# Install Netlify CLI
npm install -g netlify-cli
# Login to Netlify
netlify login
# Initialize and deploy
netlify init
# Follow prompts:
# - Create & configure a new site
# - Choose your team
# - Enter site name (e.g., broadcast-app)
# - Build command: npm run build
# - Publish directory: .output/public
# - Functions directory: .output/server
# Deploy
netlify deploy --prodIn Netlify Dashboard → Site Settings → Environment Variables, add:
# Supabase
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_KEY=your-anon-key
SUPABASE_SERVICE_KEY=your-service-role-key
# Stripe
STRIPE_SECRET_KEY=sk_live_your_secret_key
STRIPE_PUBLISHABLE_KEY=pk_live_your_publishable_key
STRIPE_WEBHOOK_SECRET=whsec_your_webhook_secret
# Stripe Price IDs
STRIPE_PRICE_STARTER=price_free
STRIPE_PRICE_CREATOR_MONTHLY=price_xxx
STRIPE_PRICE_CREATOR_YEARLY=price_xxx
STRIPE_PRICE_PROFESSIONAL_MONTHLY=price_xxx
STRIPE_PRICE_PROFESSIONAL_YEARLY=price_xxx
# Mastodon
MASTODON_CLIENT_ID=your-client-id
MASTODON_CLIENT_SECRET=your-client-secret
MASTODON_CALLBACK_URL=https://yoursite.netlify.app/api/auth/mastodon/callback
# App Configuration
SITE_URL=https://yoursite.netlify.app
CRON_SECRET=generate-a-random-secret-here
# Node Environment
NODE_ENV=productionVia Dashboard:
- Go to Site Settings → Environment Variables
- Click "Add a variable"
- Enter key and value
- Click "Save"
- Repeat for all variables
Via CLI:
# Set individual variables
netlify env:set SUPABASE_URL "https://your-project.supabase.co"
netlify env:set STRIPE_SECRET_KEY "sk_live_xxx"
# Or import from .env file
netlify env:import .env.production- Go to Supabase Dashboard → Authentication → URL Configuration
- Update:
- Site URL:
https://yoursite.netlify.app - Redirect URLs:
https://yoursite.netlify.app/confirmhttps://yoursite.netlify.app/dashboardhttps://yoursite.netlify.app/api/auth/mastodon/callback
- Site URL:
-
Webhook Endpoint:
- Go to Stripe Dashboard → Developers → Webhooks
- Click "Add endpoint"
- URL:
https://yoursite.netlify.app/api/stripe/webhook - Events: Select all subscription & payment events
- Copy webhook signing secret
- Add to Netlify environment variables as
STRIPE_WEBHOOK_SECRET
-
Checkout Success URLs:
- These are already dynamic in the code using
SITE_URL - Just ensure
SITE_URLenv var is set correctly
- These are already dynamic in the code using
- Dynamic registration handles this automatically!
- No changes needed
- In Netlify Dashboard → Domain Settings
- Click "Add custom domain"
- Enter your domain (e.g.,
broadcast.app) - Follow DNS instructions:
If using Netlify DNS:
- Transfer nameservers to Netlify
- Automatic SSL certificate
If using external DNS:
- Add CNAME record:
www→yoursite.netlify.app - Add A record:
@→ Netlify Load Balancer IP - SSL certificate auto-provisioned
After adding custom domain:
SITE_URL=https://yourdomain.com
MASTODON_CALLBACK_URL=https://yourdomain.com/api/auth/mastodon/callbackThen update all external services (Supabase, Stripe) with new URLs.
Test these URLs:
-
Homepage:
https://yoursite.netlify.app/- Should load posting interface
-
Pricing:
https://yoursite.netlify.app/pricing- Should show plans
-
Login:
https://yoursite.netlify.app/login- Should show login form
-
API Health: Check Netlify Function logs
- Site Settings → Functions → Check for errors
- Sign up: Create a test account
- Login: Verify authentication works
- Connect Platform: Try Bluesky (easiest)
- Create Post: Post something
- Check Dashboard: View post in dashboard
- Test Upgrade: Try upgrading to Creator plan
- Billing Portal: Access Stripe customer portal
- Go to Site Analytics
- View:
- Page views
- Unique visitors
- Top pages
- Bandwidth usage
- Site Settings → Functions
- Click on a function to see logs
- Monitor for errors
# Watch logs in real-time
netlify logs --follow
# Or specific function
netlify functions:logs --followError Tracking:
- Sentry - Free tier available
- Tracks JavaScript errors
- Server-side error monitoring
Uptime Monitoring:
- UptimeRobot - Free
- Checks if site is up every 5 minutes
- Email alerts on downtime
Analytics:
-
Asset Optimization:
- Site Settings → Build & Deploy → Post Processing
- ✅ Bundle CSS
- ✅ Minify CSS
- ✅ Minify JS
- ✅ Compress images
-
Edge Functions (if needed):
- For faster response times
- Available on Pro plan
Create _headers file in public directory:
/*
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()
/api/*
Cache-Control: no-cache, no-store, must-revalidate
- Images already optimized (5MB limit)
- Supabase handles database performance
- Netlify CDN serves static assets globally
- Consider Netlify Analytics for performance insights
Error: "Build exceeded time limit"
- Solution: Contact Netlify support or upgrade plan
- Usually not an issue for this app
Error: "Module not found"
# Clear dependencies and reinstall
rm -rf node_modules package-lock.json
npm install
git add package-lock.json
git commit -m "Update dependencies"
git pushError: "Environment variable not found"
- Check all required env vars are set in Netlify
- Redeploy:
netlify deploy --prod
"Failed to connect to Supabase"
- Verify
SUPABASE_URLandSUPABASE_KEY - Check Supabase project is active
- Verify redirect URLs are configured
"Stripe webhook signature invalid"
- Verify
STRIPE_WEBHOOK_SECRETmatches Stripe dashboard - Check webhook endpoint URL is correct
- Test with Stripe CLI:
stripe trigger payment_intent.succeeded
"Platform connection failed"
- Check API keys are valid
- Verify callback URLs match everywhere
- Test with Postman/curl
Usually means a serverless function crashed:
- Check function logs in Netlify
- Look for JavaScript errors
- Verify all dependencies are in
package.json - Check function execution time (10s limit on free tier)
Netlify automatically deploys when you push to main:
# Make changes
git add .
git commit -m "Add new feature"
git push origin main
# Netlify automatically builds and deploysEvery pull request gets a preview URL:
- Create a branch:
git checkout -b feature-branch - Push changes:
git push origin feature-branch - Create PR on GitHub
- Netlify creates preview URL
- Test before merging
Deploy specific branches:
- Site Settings → Build & Deploy → Branch deploys
- Add branch names to deploy
- Each gets its own URL:
branch--yoursite.netlify.app
- ✅ Bandwidth: 100 GB/month (plenty for MVP)
- ✅ Build minutes: 300/month
- ✅ Function invocations: 125K/month
- ✅ Function runtime: 10 seconds max
- ✅ Concurrent builds: 1
Consider Pro plan ($19/mo) when:
- Traffic > 100 GB/month
- Need > 300 build minutes
- Want faster build times
- Need team features
- Want password protection
- Need A/B testing
- Supabase free tier: Good for thousands of users
- Upgrade when needed (starts at $25/mo)
- No change based on hosting
- 2.9% + $0.30 per transaction
Before going live:
- All API keys in environment variables (never in code)
-
.envin.gitignore - HTTPS enabled (automatic with Netlify)
- Supabase RLS policies enabled
- Stripe webhook signature verification working
- Rate limiting considered (Supabase handles this)
- CORS configured (automatic with Nuxt)
- Security headers added (see _headers file)
- Sensitive data encrypted in database
- Authentication working correctly
- Session management secure
-
Test Everything:
- Sign up flow
- Platform connections
- Posting
- Payments
- All features
-
Set Up Monitoring:
- Add Sentry for errors
- Set up UptimeRobot
- Configure alerts
-
Marketing:
- Add to Product Hunt
- Share on Bluesky
- Post to Reddit (r/SideProject)
- Share on Hacker News
-
Documentation:
- Create user guide
- Add help center
- Create video tutorials
-
Support:
- Set up support email
- Add FAQ page
- Create Discord community
# Check deployment status
netlify status
# Open site in browser
netlify open
# Open site admin in browser
netlify open:admin
# View recent deploys
netlify deploy:list
# Roll back to previous deploy
netlify deploy:rollback
# View environment variables
netlify env:list
# View function logs
netlify functions:logs --follow
# Run functions locally
netlify devFree Tier:
- Netlify: $0
- Supabase: $0 (up to 500MB storage)
- Stripe: 2.9% + $0.30 per transaction only
Recommended Startup Stack:
- Netlify Pro: $19/mo (optional)
- Supabase Pro: $25/mo (when you hit limits)
- Total: $0-44/mo to start
Revenue Threshold to Break Even:
- At $15/user (Creator plan)
- Need ~3-4 paying customers to cover hosting
- Very achievable! 🚀
- ✅ Deploy to Netlify
- ✅ Set up environment variables
- ✅ Configure external services
- ✅ Test deployment
- ⏳ Set up cron jobs (next step!)
- 🚀 Launch and start marketing!
Your app is now live and ready to make money! 💰