Deploy Frontend
This guide covers deploying the React frontend to production.
Quick Deploy to Vercel
Vercel is the easiest platform for deploying React applications, created by the makers of Next.js.
1. Prerequisites
- GitHub account
- Vercel account (vercel.com)
- Code pushed to GitHub repository
- Backend deployed and accessible
2. Import Project
- Go to vercel.com/new
- Click "Import Project"
- Select your GitHub repository
- Vercel auto-detects Vite configuration
3. Configure Project
- Framework Preset: Vite
- Root Directory:
frontend(if in subdirectory) - Build Command:
npm run build - Output Directory:
dist - Install Command:
npm install
4. Add Environment Variables
In project settings, add:
VITE_API_URL=https://your-backend.railway.app
VITE_SUPABASE_URL=https://YOUR_PROJECT.supabase.co
VITE_SUPABASE_ANON_KEY=your_anon_keyImportant: All Vite env vars must start with VITE_
5. Deploy
Click "Deploy". Vercel builds and deploys automatically.
Your site will be live at:
https://acodeaday.vercel.app6. Configure Custom Domain (Optional)
- Go to project Settings > Domains
- Add your custom domain
- Follow DNS configuration instructions
- Vercel automatically provisions SSL certificate
7. Update Backend CORS
Add your Vercel URL to backend CORS:
# backend/app/main.py
app.add_middleware(
CORSMiddleware,
allow_origins=[
"https://acodeaday.vercel.app",
"https://yourdomain.com"
],
...
)Redeploy backend.
Deploy to Netlify
Netlify is another excellent platform with generous free tier.
1. Connect Repository
- Go to app.netlify.com
- Click "Add new site" > "Import an existing project"
- Connect to GitHub and select repository
2. Configure Build Settings
- Base directory:
frontend - Build command:
npm run build - Publish directory:
frontend/dist
3. Add Environment Variables
In Site settings > Build & deploy > Environment:
VITE_API_URL=https://your-backend.railway.app
VITE_SUPABASE_URL=https://YOUR_PROJECT.supabase.co
VITE_SUPABASE_ANON_KEY=your_anon_key4. Deploy
Click "Deploy site". Netlify builds and deploys.
Your site will be at:
https://acodeaday.netlify.app5. Configure Redirects
Create frontend/public/_redirects:
/* /index.html 200This enables client-side routing for TanStack Router.
6. Custom Domain
- Go to Site settings > Domain management
- Add custom domain
- Configure DNS
- SSL is automatic
Deploy to Cloudflare Pages
Cloudflare Pages offers excellent performance with global CDN.
1. Connect Repository
- Go to dash.cloudflare.com/pages
- Click "Create a project"
- Connect GitHub repository
2. Configure Build
- Production branch: main
- Framework preset: Vite
- Build command:
npm run build - Build output directory:
dist - Root directory:
frontend
3. Add Environment Variables
VITE_API_URL=https://your-backend.railway.app
VITE_SUPABASE_URL=https://YOUR_PROJECT.supabase.co
VITE_SUPABASE_ANON_KEY=your_anon_key
NODE_VERSION=224. Deploy
Click "Save and Deploy". Site will be at:
https://acodeaday.pages.dev5. Configure Redirects
Create frontend/public/_redirects:
/* /index.html 200Deploy to AWS S3 + CloudFront
For full control and AWS integration.
1. Build Locally
cd frontend
npm run build2. Create S3 Bucket
aws s3 mb s3://acodeaday-frontend
aws s3 website s3://acodeaday-frontend --index-document index.html3. Upload Build
aws s3 sync dist/ s3://acodeaday-frontend --delete4. Configure Bucket Policy
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::acodeaday-frontend/*"
}
]
}5. Create CloudFront Distribution
- Go to CloudFront console
- Create distribution
- Origin: Your S3 bucket
- Default root object:
index.html - Error pages: 404 →
/index.html(for client-side routing)
6. Deploy Updates
npm run build
aws s3 sync dist/ s3://acodeaday-frontend --delete
aws cloudfront create-invalidation --distribution-id YOUR_ID --paths "/*"Environment Variables Per Environment
Development
# frontend/.env.development
VITE_API_URL=http://localhost:8000
VITE_SUPABASE_URL=http://localhost:54321
VITE_SUPABASE_ANON_KEY=local_keyStaging
# frontend/.env.staging
VITE_API_URL=https://staging-api.yourapp.com
VITE_SUPABASE_URL=https://staging.supabase.co
VITE_SUPABASE_ANON_KEY=staging_keyProduction
# frontend/.env.production
VITE_API_URL=https://api.yourapp.com
VITE_SUPABASE_URL=https://prod.supabase.co
VITE_SUPABASE_ANON_KEY=prod_keyVite automatically uses the correct .env file based on build mode.
Optimization
Enable Compression
Most platforms (Vercel, Netlify, Cloudflare) enable Gzip/Brotli automatically.
Code Splitting
Vite automatically code-splits by route. Verify in build output:
npm run build
# Output shows chunk sizes:
# dist/assets/index-a1b2c3.js 142.50 kB
# dist/assets/Problem-x7y8z9.js 45.20 kBPreload Critical Assets
In index.html:
<link rel="preload" href="/fonts/inter.woff2" as="font" type="font/woff2" crossorigin>Analyze Bundle Size
npm install -D rollup-plugin-visualizerUpdate vite.config.ts:
import { visualizer } from 'rollup-plugin-visualizer';
export default defineConfig({
plugins: [
react(),
visualizer({ open: true })
]
});Run npm run build to see bundle analysis.
Performance Best Practices
1. Enable Caching
Vite automatically adds content hashes to filenames for long-term caching.
2. Lazy Load Routes
TanStack Router supports code splitting:
// routes/problem.$slug.tsx
export const Route = createFileRoute('/problem/$slug')({
component: lazy(() => import('@/components/ProblemView'))
})3. Optimize Images
- Use modern formats (WebP, AVIF)
- Compress images
- Use
loading="lazy"attribute
4. Minimize Dependencies
Review and remove unused packages:
npx depcheckMonitoring
Add Analytics
Vercel Analytics:
npm install @vercel/analyticsimport { Analytics } from '@vercel/analytics/react'
function App() {
return (
<>
<YourApp />
<Analytics />
</>
)
}Google Analytics:
npm install react-ga4Error Tracking
Sentry:
npm install @sentry/reactimport * as Sentry from "@sentry/react";
Sentry.init({
dsn: "your-sentry-dsn",
environment: "production",
integrations: [new Sentry.BrowserTracing()],
tracesSampleRate: 1.0,
});Security Headers
Vercel
Create vercel.json:
{
"headers": [
{
"source": "/(.*)",
"headers": [
{
"key": "X-Content-Type-Options",
"value": "nosniff"
},
{
"key": "X-Frame-Options",
"value": "DENY"
},
{
"key": "X-XSS-Protection",
"value": "1; mode=block"
}
]
}
]
}Netlify
Create netlify.toml:
[[headers]]
for = "/*"
[headers.values]
X-Frame-Options = "DENY"
X-XSS-Protection = "1; mode=block"
X-Content-Type-Options = "nosniff"CI/CD
Automatic Deploys
Vercel, Netlify, and Cloudflare Pages automatically deploy on Git push:
- main branch → Production
- develop branch → Preview (optional)
- Pull requests → Preview deployments
Preview Deployments
Every PR gets a unique preview URL:
https://acodeaday-pr-123.vercel.appPerfect for testing before merge!
Troubleshooting
Blank page after deploy
- Check browser console for errors
- Verify environment variables are set
- Check API URL is accessible
- Ensure CORS allows your frontend domain
404 on page refresh
Add redirect rule:
/* /index.html 200Environment variables not working
- Verify they start with
VITE_ - Rebuild after adding env vars
- Check they're set in platform dashboard
Build fails
# Check build locally
npm run build
# Check Node.js version matches
node --version # Should be 22+Next Steps
- Environment Variables - Complete reference
- Backend Deployment - Deploy the API
- Deployment Overview - Architecture overview