This guide explains how to securely configure the Google Gemini API for the Poetics Studio website.
┌─────────────────┐
│ Components │
│ (Client-Side) │
│ │
│ • Iconoclast │
│ • Sonic Arch │
└────────┬────────┘
│
│ POST /api/generate
│
▼
┌─────────────────┐
│ Vercel Edge │
│ Function │
│ (Server-Side) │
│ │
│ api/generate.ts│
└────────┬────────┘
│
│ Uses GEMINI_API_KEY
│ (From Environment)
▼
┌─────────────────┐
│ Google Gemini │
│ API │
└─────────────────┘
-
API Routes:
/api/generate- Text generation for Iconoclast (design history analysis)/api/analyze-architecture- Image analysis for Sonic Architecture (floorplan to music)
-
Security Features:
- CORS headers configured
- POST-only requests
- Input validation
- Error handling
- Rate limiting (via Vercel)
-
Components Using API:
- ✅ PoeticMachine (Iconoclast) -
/components/PoeticMachine.tsx→/api/generate - ✅ Sonic Architecture -
/sonic-architecture/services/geminiService.ts→/api/analyze-architecture
- ✅ PoeticMachine (Iconoclast) -
-
Get Your Gemini API Key:
- Visit: https://aistudio.google.com/app/apikey
- Create a new API key
- Copy the key
-
Create Local Environment File:
# In the project root, create .env.local touch .env.local -
Add Your API Key:
# .env.local GEMINI_API_KEY=your_actual_api_key_here
-
Restart Dev Server:
npm run dev
-
Login to Vercel Dashboard:
- Go to: https://vercel.com/dashboard
- Select your project
-
Add Environment Variable:
- Navigate to: Settings → Environment Variables
- Click Add New
- Enter:
- Name:
GEMINI_API_KEY - Value:
your_actual_api_key - Environments: Select Production, Preview, and Development
- Note: Only Production allows "Sensitive" toggle - that's okay! Mark it sensitive for Production, but add to all three environments for preview deployments and
vercel devto work.
- Name:
-
Redeploy:
- Vercel will automatically redeploy
- Or manually trigger: Deployments → Redeploy
- Never commit
.env.local- Already in.gitignore - Use Vercel Environment Variables for production
- Keep API keys server-side only
- Monitor API usage in Google Cloud Console
- Set usage quotas in Google Cloud to prevent abuse
- Never hardcode API keys in component files
- Never commit keys to Git
- Never expose keys in client-side code
- Never share
.env.localfiles
Request Format:
const response = await fetch('/api/generate', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
input: 'chair' // User's input
}),
});
const data = await response.json();
console.log(data.text); // AI responseResponse Format:
Success:
{
"text": "the eames lounge chair (1956) challenged notions of comfort..."
}Error:
{
"error": "Invalid input"
}Request Format:
const response = await fetch('/api/analyze-architecture', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
base64Image: 'base64_encoded_image_data_without_prefix',
mimeType: 'image/jpeg' // or 'image/png', etc.
}),
});
const data = await response.json();
console.log(data); // Sonic analysis dataResponse Format:
Success:
{
"volume": 0.7,
"brightness": 0.8,
"complexity": 0.5,
"materials": "Glass, Steel",
"mood": "Modern, Minimalist",
"suggestedKey": "C Major",
"tempo": 120,
"genre": "Ambient",
"detectedFeatures": ["Open floor plan", "Large windows", "Minimal furniture"],
"architecturalDescription": "A bright, airy space with flowing acoustics..."
}Error:
{
"error": "Invalid image data",
"details": "Error message here"
}# 1. Make sure .env.local has your key
cat .env.local
# 2. Start dev server
npm run dev
# 3. Test the Iconoclast on the Experiments page
# Enter an object like "chair" and click submitcurl -X POST http://localhost:5173/api/generate \
-H "Content-Type: application/json" \
-d '{"input":"chair"}'- Go to: https://console.cloud.google.com/
- Select your project
- Navigate to: APIs & Services → Dashboard
- View Gemini API usage
- Go to: IAM & Admin → Quotas
- Filter for "Gemini API"
- Set daily/monthly limits to prevent abuse
Cause: GEMINI_API_KEY not set in environment
Fix:
- Local: Check
.env.localexists and has the key - Production: Add the key in Vercel dashboard
Cause: Using GET instead of POST
Fix: Ensure you're making POST requests to /api/generate
Cause: Cross-origin request blocked
Fix: API already has CORS headers configured. If issue persists:
- Check Vercel deployment logs
- Ensure you're calling from the same domain
Cause: Too many requests
Fix:
- Implement client-side debouncing
- Add rate limiting in API route (see below)
To add rate limiting to the API route:
// api/generate.ts
import rateLimit from 'express-rate-limit';
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100 // limit each IP to 100 requests per windowMs
});
export default async function handler(req, res) {
await limiter(req, res);
// ... rest of handler
}- Get Gemini API key from Google AI Studio
- Create
.env.localwith your key - Test locally with Iconoclast
- Add key to Vercel dashboard
- Deploy and test in production
- Update Sonic Architecture to use API route
- Set API usage quotas in Google Cloud