Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,25 +98,28 @@ Transform any content into optimized formats across 15+ platforms using our neur

## 📦 Deployment

> **✅ DEPLOYMENT ISSUES FIXED**: See [VERCEL_DEPLOYMENT_FIX.md](./VERCEL_DEPLOYMENT_FIX.md) for solutions to common deployment problems.

### One-Click Deploy
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/djtlb/contentflow)

### Manual Deployment

1. **Frontend Deployment**
- Connect GitHub repository to Vercel
- Framework: React (Vite)
- Build command: `pnpm run build`
- Framework: React (Vite) - auto-detected
- Build command: `pnpm build`
- Output directory: `dist`

2. **API Deployment**
- Create separate Vercel project for `/api` folder
- Framework: Node.js
- Framework: Node.js - auto-detected
- Build command: `npm install`

3. **Environment Variables**
- Add all environment variables to Vercel dashboard
- Configure production URLs
- See [VERCEL_DEPLOYMENT_FIX.md](./VERCEL_DEPLOYMENT_FIX.md) for required variables

### Custom Domain
- Purchase domain (recommended: `.ai`, `.co`, or `.io`)
Expand Down
96 changes: 96 additions & 0 deletions VERCEL_DEPLOYMENT_FIX.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# Vercel Deployment Fix Guide

## Common Issues Fixed

### 1. CSS Build Errors ✅ FIXED
- **Issue**: `@import must precede all other statements`
- **Solution**: Moved `@import` statements to the top of `src/styles/viral-brand.css`

### 2. CORS Issues ✅ FIXED
- **Issue**: API not accessible from deployed frontend
- **Solution**: Updated CORS configuration to dynamically allow Vercel domains

### 3. Environment Variables ✅ IMPROVED
- **Issue**: Missing or placeholder environment variables
- **Solution**: Added validation and better error messages

### 4. Vercel Configuration ✅ IMPROVED
- **Issue**: Inconsistent build settings
- **Solution**: Updated vercel.json files with proper framework settings

## Required Environment Variables

### Frontend (vercel.com dashboard)
```
VITE_SUPABASE_URL=https://your-project.supabase.co
VITE_SUPABASE_ANON_KEY=your-supabase-anon-key
VITE_STRIPE_PUBLISHABLE_KEY=pk_live_... (or pk_test_...)
```

### API (separate vercel project)
```
OPENAI_API_KEY=sk-...
VITE_SUPABASE_URL=https://your-project.supabase.co
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key
STRIPE_SECRET_KEY=sk_live_... (or sk_test_...)
STRIPE_WEBHOOK_SECRET=whsec_...
STRIPE_CREATOR_PRICE_ID=price_...
STRIPE_PRO_PRICE_ID=price_...
FRONTEND_URL=https://your-frontend-domain.vercel.app
NODE_ENV=production
```

## Deployment Steps

### 1. Frontend Deployment
1. Push code to GitHub
2. Connect GitHub repo to Vercel
3. Framework will auto-detect as "Vite"
4. Build command: `pnpm build` (auto-detected)
5. Output directory: `dist` (auto-detected)
6. Add environment variables in Vercel dashboard
7. Deploy

### 2. API Deployment
1. Create new Vercel project
2. Connect to same GitHub repo
3. Set root directory to `api`
4. Framework will auto-detect as "Node.js"
5. Add ALL API environment variables
6. Deploy

### 3. Connect Frontend to API
1. Update `FRONTEND_URL` in API environment variables to your frontend URL
2. Redeploy API
3. Test connection

## Verification Steps

1. **Frontend Build**: No CSS warnings during build
2. **API Health**: `https://your-api-domain.vercel.app/api/health` returns JSON
3. **CORS**: Frontend can make requests to API
4. **Environment**: No missing environment variable errors

## Troubleshooting

### Build Fails with CSS Errors
- ✅ Fixed: CSS imports now at top of file

### API Returns CORS Errors
- ✅ Fixed: Dynamic CORS configuration

### "Environment variable not defined" errors
- Check Vercel dashboard environment variables
- Ensure no placeholder values like "your-key-here"
- Redeploy after adding variables

### Functions timeout
- ✅ Added: 30-second timeout for API functions
- Consider upgrading Vercel plan for longer timeouts

## Success Indicators

- ✅ Frontend builds without warnings
- ✅ API deploys and health endpoint responds
- ✅ No CORS errors in browser console
- ✅ Environment variables properly configured
42 changes: 41 additions & 1 deletion api/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,22 @@ import authMiddleware from './middleware/auth.js'
// Load environment variables
dotenv.config({ path: '../.env.local' })

// Environment validation
const requiredEnvVars = {
'VITE_SUPABASE_URL': process.env.VITE_SUPABASE_URL,
'SUPABASE_SERVICE_ROLE_KEY': process.env.SUPABASE_SERVICE_ROLE_KEY,
'OPENAI_API_KEY': process.env.OPENAI_API_KEY
}

const missingEnvVars = Object.entries(requiredEnvVars)
.filter(([key, value]) => !value || value.includes('your-') || value.includes('${'))
.map(([key]) => key)

if (missingEnvVars.length > 0 && process.env.NODE_ENV === 'production') {
console.error('❌ Missing or invalid environment variables:', missingEnvVars.join(', '))
console.error('Please configure these environment variables in your Vercel dashboard')
}

const app = express()
const PORT = process.env.PORT || 3001

Expand All @@ -20,8 +36,32 @@ export const supabase = createClient(
)

// Middleware
const allowedOrigins = [
'http://localhost:5173',
'http://localhost:3000',
'http://localhost:5174',
process.env.FRONTEND_URL,
...(process.env.VERCEL_URL ? [`https://${process.env.VERCEL_URL}`] : []),
...(process.env.FRONTEND_URL ? [process.env.FRONTEND_URL] : [])
].filter(Boolean)

app.use(cors({
origin: ['http://localhost:5173', 'http://localhost:3000'],
origin: function (origin, callback) {
// Allow requests with no origin (like mobile apps or curl)
if (!origin) return callback(null, true)

// Allow any vercel.app domain in production
if (process.env.NODE_ENV === 'production' && origin.includes('.vercel.app')) {
return callback(null, true)
}

if (allowedOrigins.includes(origin)) {
callback(null, true)
} else {
console.warn(`CORS: Origin ${origin} not allowed`)
callback(new Error('Not allowed by CORS'))
}
},
credentials: true
}))
app.use(express.json({ limit: '10mb' }))
Expand Down
8 changes: 7 additions & 1 deletion api/vercel.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@
"dest": "/server.js"
}
],
"functions": {
"server.js": {
"maxDuration": 30
}
},
"env": {
"OPENAI_API_KEY": "@openai_api_key",
"VITE_SUPABASE_URL": "@supabase_url",
Expand All @@ -20,6 +25,7 @@
"STRIPE_WEBHOOK_SECRET": "@stripe_webhook_secret",
"STRIPE_CREATOR_PRICE_ID": "@stripe_creator_price_id",
"STRIPE_PRO_PRICE_ID": "@stripe_pro_price_id",
"FRONTEND_URL": "@frontend_url"
"FRONTEND_URL": "@frontend_url",
"NODE_ENV": "production"
}
}
41 changes: 0 additions & 41 deletions dist/assets/index-BTgx3oLx.js

This file was deleted.

1 change: 0 additions & 1 deletion dist/assets/index-Dj7fSDCK.css

This file was deleted.

1 change: 0 additions & 1 deletion dist/assets/router-Dyxtdz5J.js

This file was deleted.

1 change: 0 additions & 1 deletion dist/assets/supabase-Ch0sirx8.js

This file was deleted.

20 changes: 0 additions & 20 deletions dist/assets/ui-CZBkdTqY.js

This file was deleted.

21 changes: 0 additions & 21 deletions dist/assets/vendor-T8osx3Jj.js

This file was deleted.

12 changes: 6 additions & 6 deletions dist/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>ContentFlow - AI Content Repurposing Tool</title>
<script type="module" crossorigin src="/assets/index-BTgx3oLx.js"></script>
<link rel="modulepreload" crossorigin href="/assets/vendor-T8osx3Jj.js">
<link rel="modulepreload" crossorigin href="/assets/ui-CZBkdTqY.js">
<link rel="modulepreload" crossorigin href="/assets/supabase-Ch0sirx8.js">
<link rel="modulepreload" crossorigin href="/assets/router-Dyxtdz5J.js">
<link rel="stylesheet" crossorigin href="/assets/index-Dj7fSDCK.css">
<script type="module" crossorigin src="/assets/index-BEV6vtdE.js"></script>
<link rel="modulepreload" crossorigin href="/assets/vendor-NuYkQVOp.js">
<link rel="modulepreload" crossorigin href="/assets/ui-B1g3F0Qu.js">
<link rel="modulepreload" crossorigin href="/assets/supabase-B-TuLt8T.js">
<link rel="modulepreload" crossorigin href="/assets/router-G9zlSsQi.js">
<link rel="stylesheet" crossorigin href="/assets/index-DkhEkmAB.css">
</head>
<body>
<div id="root"></div>
Expand Down
17 changes: 0 additions & 17 deletions node_modules/.bin/acorn

This file was deleted.

17 changes: 0 additions & 17 deletions node_modules/.bin/browserslist

This file was deleted.

8 changes: 4 additions & 4 deletions node_modules/.bin/eslint

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading