Skip to content
Merged
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
8 changes: 8 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Imgflip API Credentials
# Get these from https://imgflip.com/signup (free account)
# Then go to https://imgflip.com/api to get your credentials
IMGFLIP_USERNAME=your_imgflip_username_here
IMGFLIP_PASSWORD=your_imgflip_password_here

# Optional: Backend API URL for AI meme generator
VITE_API_BASE_URL=http://localhost:5000
25 changes: 25 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module.exports = {
root: true,
env: {
browser: true,
es2020: true,
node: true
},
extends: [
'eslint:recommended',
'@typescript-eslint/recommended',
'plugin:react-hooks/recommended',
],
ignorePatterns: ['dist', '.eslintrc.cjs'],
parser: '@typescript-eslint/parser',
plugins: ['react-refresh'],
rules: {
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
'no-undef': 'off', // Allow process, global, etc.
'no-unused-vars': 'warn', // Make unused vars warnings instead of errors
'react/prop-types': 'off', // Disable prop-types validation
},
}
93 changes: 93 additions & 0 deletions DEPLOYMENT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# Vercel Deployment Guide

## ✅ Vercel Deployment Ready!

This MemeGenerator project is fully configured for Vercel deployment.

### 🚀 Quick Deploy Steps:

1. **Push to GitHub**:
```bash
git add .
git commit -m "Ready for Vercel deployment"
git push origin main
```

2. **Deploy on Vercel**:
- Go to [vercel.com](https://vercel.com)
- Import your GitHub repository
- Vercel will auto-detect it as a Vite project

3. **Set Environment Variables** (in Vercel Dashboard):
```
IMGFLIP_USERNAME=your_imgflip_username
IMGFLIP_PASSWORD=your_imgflip_password
```

### 🎯 What's Included:

#### ✅ Frontend (Vite + React):
- **Build Command**: `npm run build`
- **Output Directory**: `dist`
- **Node Version**: 22.x (specified in package.json)

#### ✅ API Functions:
- **Serverless Function**: `/api/caption.js`
- **Runtime**: Node.js 18.x
- **CORS Headers**: Configured for cross-origin requests

#### ✅ Canvas Generation:
- **Client-side**: Works in browser without server dependencies
- **Fallback**: API integration with Imgflip
- **No External Dependencies**: All canvas utilities are self-contained

### 🔧 Vercel Configuration:

The `vercel.json` file includes:
- **Function runtime** specification
- **API rewrites** for proper routing
- **CORS headers** for API endpoints

### 🎨 Features That Work on Vercel:

1. **Meme Templates**: Fetched from Imgflip API
2. **Canvas Generation**: Client-side text overlay
3. **API Fallback**: Server-side meme generation
4. **Social Sharing**: All sharing features
5. **Download**: Meme download functionality
6. **History**: Local storage meme history

### 🛠 Build Process:

Vercel will automatically:
1. **Install dependencies**: `npm install`
2. **Build frontend**: `npm run build`
3. **Deploy API functions**: Auto-deploy `/api/caption.js`
4. **Serve static files**: From `dist` folder

### 🌐 Post-Deployment:

After deployment, your app will have:
- **Frontend**: `https://your-app.vercel.app`
- **API Endpoint**: `https://your-app.vercel.app/api/caption`
- **Canvas Generation**: Works immediately
- **Imgflip Integration**: Works with environment variables

### 🔍 Troubleshooting:

If deployment fails:
1. **Check build logs** in Vercel dashboard
2. **Verify environment variables** are set
3. **Test API endpoint** manually
4. **Check function logs** for errors

### 📊 Performance:

- **Frontend**: Static files served via Vercel CDN
- **API**: Serverless functions with global edge network
- **Canvas**: Client-side processing (no server load)
- **Images**: Cached and optimized by Vercel

## 🎉 Ready to Deploy!

Your MemeGenerator is production-ready for Vercel deployment!
55 changes: 55 additions & 0 deletions SETUP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Meme Generator Setup Guide

## ✅ Current Status: WORKING IN DEMO MODE

The meme generator is now running with demo mode enabled! You can test it immediately.

## 🚀 Quick Start

1. **Run the project:**
```bash
npm run dev:full
```

2. **Open your browser:** http://localhost:5173/

3. **Test it:** Select a meme template, add captions, and click "Generate Meme"

## 🎯 Demo Mode vs Real Mode

### Demo Mode (Current)
- ✅ Works immediately without setup
- ✅ Shows placeholder images with your text
- ✅ Perfect for testing the interface
- ⚠️ Uses placeholder images instead of real memes

### Real Mode (Optional)
To generate actual memes with Imgflip:

1. **Get Imgflip Credentials (Free):**
- Sign up at [imgflip.com/signup](https://imgflip.com/signup)
- Your username and password are your API credentials

2. **Update `.env.local`:**
```
IMGFLIP_USERNAME=your_actual_username
IMGFLIP_PASSWORD=your_actual_password
```

3. **Restart the server:**
```bash
npm run dev:full
```

## 🛠 Development Commands

- `npm run dev` - Frontend only
- `npm run dev:api` - API server only
- `npm run dev:full` - Both servers (recommended)

## 🎉 What's Working

- ✅ Frontend running on http://localhost:5173/
- ✅ API server running on http://localhost:3001/
- ✅ Demo mode for immediate testing
- ✅ Real Imgflip integration ready when you add credentials
78 changes: 78 additions & 0 deletions dev-server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Development server to handle API calls locally
import express from 'express';
import cors from 'cors';
import fetch from 'node-fetch';
import dotenv from 'dotenv';

// Load environment variables
dotenv.config({ path: '.env.local' });

const app = express();
const PORT = 3001;

app.use(cors());
app.use(express.json());

// Caption API endpoint - same logic as api/caption.js
app.post('/api/caption', async (req, res) => {
try {
const { template_id, boxes = [], username, password } = req.body || {};

if (!template_id) {
return res.status(400).json({ success: false, error: 'template_id is required' });
}

const user = username || process.env.IMGFLIP_USERNAME;
const pass = password || process.env.IMGFLIP_PASSWORD;

// Demo mode - if no credentials or demo credentials, return a mock response
if (!user || !pass || user === 'demo_user' || user === 'your_imgflip_username_here') {
console.log('Demo mode: returning mock meme response');

// Create a demo response with a placeholder image that shows the text
const demoText = boxes.map(box => box.text || '').join(' / ');
const encodedText = encodeURIComponent(`Demo Meme: ${demoText}`);

return res.status(200).json({
success: true,
data: {
url: `https://via.placeholder.com/400x400/FF6B6B/FFFFFF?text=${encodedText}`,
page_url: 'https://imgflip.com/demo'
}
});
}

const params = new URLSearchParams();
params.append('template_id', String(template_id));
params.append('username', user);
params.append('password', pass);

(boxes || []).forEach((box, i) => {
const val = box && typeof box.text === 'string' ? box.text : '';
params.append(`boxes[${i}][text]`, val);
});

const resp = await fetch('https://api.imgflip.com/caption_image', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: params.toString(),
});

const data = await resp.json();

// Normalize response
if (data && data.success) {
return res.status(200).json({ success: true, data: data.data });
}

return res.status(400).json({ success: false, error: data?.error_message || 'Imgflip error' });
} catch (err) {
console.error('caption proxy error:', err);
return res.status(500).json({ success: false, error: 'Internal server error' });
}
});

app.listen(PORT, () => {
console.log(`Development API server running on http://localhost:${PORT}`);
console.log('Make sure your .env.local file has IMGFLIP_USERNAME and IMGFLIP_PASSWORD set');
});
Loading