AI Coding Tools

Command Palette

Search for a command to run...

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.