This guide shows how to connect your Admin Panel to your Cloudflare Worker backend.
Update src/components/AdminPanel.tsx to use environment variables and your API URL:
const response = await fetch('/api/upload', {const API_URL = import.meta.env.VITE_API_URL || '/api';
// Then use:
const response = await fetch(`${API_URL}/upload`, {VITE_ADMIN_PASSWORD=your-secure-password-here
VITE_API_URL=https://your-worker.workers.dev
const ADMIN_PASSWORD = import.meta.env.VITE_ADMIN_PASSWORD || 'wedding2026';
const API_URL = import.meta.env.VITE_API_URL || '/api';.env.local to .gitignore:
.env.local
.env.*.local
Replace all hardcoded /api paths with API_URL:
// BEFORE:
const response = await fetch('/api/upload', {
// AFTER:
const response = await fetch(`${API_URL}/upload`, {// BEFORE:
await fetch(`/api/photos/${id}`, {
// AFTER:
await fetch(`${API_URL}/photos/${id}`, {// BEFORE:
await fetch(`/api/videos/${id}`, {
// AFTER:
await fetch(`${API_URL}/videos/${id}`, {// BEFORE:
const response = await fetch('/api/wedding-details', {
// AFTER:
const response = await fetch(`${API_URL}/wedding-details`, {Here's the corrected hooks section to add at the top of AdminPanel component:
const AdminPanel = () => {
// Environment configuration
const API_URL = import.meta.env.VITE_API_URL || '/api';
const ADMIN_PASSWORD = import.meta.env.VITE_ADMIN_PASSWORD || 'wedding2026';
// ... rest of component code# Terminal 1: Your Vite app
npm run dev
# Terminal 2: Your Cloudflare Worker
cd wedding-api
wrangler devAccess: http://localhost:5173/admin
The app will connect to http://localhost:8787 (Wrangler dev server).
Once deployed:
- Admin panel at:
https://your-site.com/admin - API calls go to:
https://your-worker.workers.dev
Your admin panel expects these response formats:
{
"url": "https://your-bucket.r2.dev/photo-123.jpg",
"id": "photo-123",
"title": "My Photo"
}{
"error": "File too large"
}{
"success": true
}Your Cloudflare Worker must handle CORS. See CLOUDFLARE_WORKER_SETUP.md for headers.
Key headers needed:
Access-Control-Allow-Origin: https://your-site.com
Access-Control-Allow-Methods: GET, POST, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type
- Open DevTools (F12)
- Go to "Network" tab
- Try uploading a photo
- Look for the fetch request
- Check Response tab for errors
Add to AdminPanel.tsx:
const handleUploadPhoto = async () => {
console.log('Starting upload...');
try {
console.log('Uploading to:', `${API_URL}/upload`);
const response = await fetch(`${API_URL}/upload`, {
method: 'POST',
body: formData,
});
console.log('Response status:', response.status);
const data = await response.json();
console.log('Response data:', data);
// ... rest of code
} catch (error) {
console.error('Upload error:', error);
}
};- Changed admin password
- Updated API_URL for production
- Tested locally
- Added .env.local to .gitignore
cd wedding-api
wrangler deploycd ..
npm run build
# Deploy dist/ folder to Vercel/Netlify- Admin panel accessible at /admin
- Photo upload works
- Videos upload works
- Can delete items
- Wedding details save
Cause: CORS error or API endpoint wrong Solution: Check Network tab, verify API_URL, check CORS headers in Worker
Cause: Getting HTML error page instead of JSON Solution: Worker is returning error page, check Worker logs
Cause: Database not connected or wrong table Solution: Add logging to Worker, check Neon connection
Cause: API_URL domain not allowed Solution: Update CORS headers in Worker to include your domain
β
VITE_ADMIN_PASSWORD=secure-password
β
VITE_API_URL=https://worker.workers.dev
β
DATABASE_URL=postgresql://...
β
AWS_BUCKET_NAME=your-bucket
β
R2_BUCKET_NAME=your-bucket (if using R2)
Once this works, you can:
- Connect to Neon PostgreSQL
- Store photos/videos metadata
- Persist wedding details
- Add more features
See CLOUDFLARE_WORKER_SETUP.md for database examples.
Good luck! Let me know if you hit any issues. π