Build a DALL-E 3 Image Generator App With Next.js
AAdmin
15 tháng 3, 2026
6 phút đọc
0 lượt xem
DALL-E 3 produces stunning images from text prompts. Build a polished image generation app with prompt history, style presets, and image gallery using Next.js and the OpenAI API.
What We're Building
A full-stack image generator with: a prompt input with style presets, image generation via DALL-E 3, a gallery of generated images stored in Postgres, and download functionality. This is a practical starting point for any AI-powered image feature.
The Generation API Route
// app/api/generate-image/route.ts
import OpenAI from 'openai';
import { db } from '@/lib/db';
const openai = new OpenAI();
export async function POST(request: Request) {
const { prompt, style, size } = await request.json();
// Enhance prompt with style modifier
const styleModifiers: Record<string, string> = {
photorealistic: 'photorealistic, high detail, 8K resolution',
illustration: 'digital illustration, vibrant colors, clean lines',
'3d-render': '3D render, cinema 4D, octane render, soft lighting',
watercolor: 'watercolor painting, soft washes, artistic',
};
const enhancedPrompt = style
? `${prompt}. Style: ${styleModifiers[style] ?? style}`
: prompt;
const response = await openai.images.generate({
model: 'dall-e-3',
prompt: enhancedPrompt,
n: 1,
size: size ?? '1024x1024',
quality: 'hd',
response_format: 'url',
});
const imageUrl = response.data[0].url!;
const revisedPrompt = response.data[0].revised_prompt;
// Store in database
const saved = await db.generatedImage.create({
data: {
prompt,
revisedPrompt,
imageUrl,
style,
size: size ?? '1024x1024',
},
});
return Response.json({ id: saved.id, imageUrl, revisedPrompt });
}
The Image Generator UI
'use client';
import { useState } from 'react';
const STYLES = [
{ id: 'none', label: 'No Style' },
{ id: 'photorealistic', label: 'Photo' },
{ id: 'illustration', label: 'Illustration' },
{ id: '3d-render', label: '3D Render' },
{ id: 'watercolor', label: 'Watercolor' },
];
export function ImageGenerator() {
const [prompt, setPrompt] = useState('');
const [style, setStyle] = useState('none');
const [imageUrl, setImageUrl] = useState('');
const [revisedPrompt, setRevisedPrompt] = useState('');
const [loading, setLoading] = useState(false);
async function generate() {
if (!prompt.trim()) return;
setLoading(true);
setImageUrl('');
const res = await fetch('/api/generate-image', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ prompt, style: style === 'none' ? null : style }),
});
const data = await res.json();
setImageUrl(data.imageUrl);
setRevisedPrompt(data.revisedPrompt);
setLoading(false);
}
return (
<div className="max-w-2xl mx-auto p-6">
<h1 className="text-2xl font-bold mb-6">AI Image Generator</h1>
<textarea
value={prompt}
onChange={e => setPrompt(e.target.value)}
placeholder="Describe the image you want to create..."
className="w-full p-3 border rounded-lg h-24 resize-none"
/>
<div className="flex gap-2 my-3">
{STYLES.map(s => (
<button
key={s.id}
onClick={() => setStyle(s.id)}
className={`px-3 py-1 rounded-full text-sm border transition-colors ${
style === s.id ? 'bg-blue-600 text-white border-blue-600' : 'hover:bg-gray-50'
}`}
>
{s.label}
</button>
))}
</div>
<button
onClick={generate}
disabled={loading || !prompt.trim()}
className="w-full py-3 bg-blue-600 text-white rounded-lg font-semibold disabled:opacity-50"
>
{loading ? 'Generating... (30-60s)' : 'Generate Image'}
</button>
{loading && (
<div className="mt-6 aspect-square bg-gray-100 rounded-xl animate-pulse flex items-center justify-center">
<p className="text-gray-400">DALL-E 3 is painting your image...</p>
</div>
)}
{imageUrl && !loading && (
<div className="mt-6">
<img src={imageUrl} alt={prompt} className="w-full rounded-xl shadow-lg" />
{revisedPrompt && (
<p className="mt-3 text-sm text-gray-500">
<strong>Revised prompt:</strong> {revisedPrompt}
</p>
)}
<a
href={imageUrl}
download="generated.png"
className="mt-3 inline-block px-4 py-2 bg-gray-800 text-white rounded text-sm"
>
Download
</a>
</div>
)}
</div>
);
}
Key DALL-E 3 Tips
- DALL-E 3 rewrites your prompt for better results — always log
revised_prompt - Use
quality: "hd"for production; it's twice the cost but significantly better - 1024x1792 and 1792x1024 are great for portrait/landscape use cases
- DALL-E 3 costs $0.040 per standard image, $0.080 per HD — factor this into your pricing
Tác giảA
Admin
Open SourceSponsored
Cal.com
Open source scheduling — tự host booking system, thay thế Calendly. Free & privacy-first.
Bình luận (0)
Đăng nhập để bình luận
Chưa có bình luận nào. Hãy là người đầu tiên!