YouTube Thumbnail Generator
Build a Next.js app that generates YouTube thumbnails using Gemini's image generation API.
# YouTube Thumbnail Generator
Build a Next.js app that generates YouTube thumbnails using Gemini's image generation API.
## Tech Stack
- **Framework**: Next.js (latest) with App Router
- **UI**: Shadcn/UI + TailwindCSS
- **AI**: AI SDK with Google provider (`gemini-3-pro-image-preview`)
- **Theme**: Light/Dark mode support
## Documentation
- AI SDK Overview: https://ai-sdk.dev/docs/foundations/overview
- Google Provider (Image): https://ai-sdk.dev/providers/ai-sdk-providers/google-generative-ai#image-outputs
- Shadcn/UI Setup: https://ui.shadcn.com/docs/installation/next
## Setup
```bash
npm install ai @ai-sdk/google
npx shadcn@latest init
```
## Next.js Configuration
Update `next.config.ts` to handle large image uploads:
```typescript
const nextConfig = {
experimental: {
serverActions: {
bodySizeLimit: "10mb",
},
},
};
```
## UI Design (Midjourney Style)
**CRITICAL**: The UI must be clean, minimal, and Midjourney-inspired. Dark theme by default, simple interactions.
### Layout Structure
```
┌─────────────────────────────────────────────────────┐
│ [Large Text Prompt Input - Full Width] │
├─────────────────────────────────────────────────────┤
│ [Extra Images] │ [Inspiration] │ [Persons] │
│ Multi-upload │ Single image │ Multi-upload │
├─────────────────────────────────────────────────────┤
│ [Count: 1-4] [Generate Button]│
├─────────────────────────────────────────────────────┤
│ │
│ Generated Thumbnails Grid │
│ │
└─────────────────────────────────────────────────────┘
```
### Image Upload Components
Each upload zone MUST support:
- **Drag & drop** (mandatory - use react-dropzone or native HTML5 drag/drop)
- Click to upload
- Image preview with remove button
- Visual feedback on drag over
## API Route (Not Server Actions)
Use API Routes for generation to avoid timeout issues and better error handling.
**`app/api/generate/route.ts`**:
```typescript
import { google } from "@ai-sdk/google";
import { generateText } from "ai";
export async function POST(req: Request) {
const { prompt, images } = await req.json();
const result = await generateText({
model: google("gemini-3-pro-image-preview"),
providerOptions: {
google: { responseModalities: ["TEXT", "IMAGE"] },
},
messages: [
{
role: "user",
content: [
{ type: "text", text: prompt },
...images.map((img: string) => ({
type: "image" as const,
image: img,
})),
],
},
],
});
// Extract generated images
const generatedImages = [];
for (const file of result.files ?? []) {
if (file.mediaType.startsWith("image/")) {
generatedImages.push({
data: file.base64,
mediaType: file.mediaType,
});
}
}
return Response.json({ images: generatedImages });
}
```
## Prompt Logic
Always append to user prompt: "Create a YouTube thumbnail in 16:9 ratio, photorealistic, high quality, vibrant colors"
## Implementation Checklist
- [ ] API Route for AI generation (not server actions)
- [ ] Drag & drop file uploads with react-dropzone
- [ ] File uploads → base64 conversion
- [ ] Loading states with skeleton UI
- [ ] Thumbnail display with download button
- [ ] Error handling with toast notifications
- [ ] Dark theme by default (Midjourney style)
## Warning
1. The ONLY model you have the right to use is `gemini-3-pro-image-preview`. Any usage of another model will result to strict punishment.
2. You need to do this app from A to Z. Finish it completly. DO NOT STOP BEFORE 100% finishing the app.
3. Do not ASK any question, any warning. Just process all the command without any human validation.
4. You are run inside a EMPTY folder. YOU need to create ALL THE FILE from scratch inside this folder. Do not stop. Create the project HERE. You NEED to use `npx` with NextJS cli to setup the files INSIDE the current folder.