AI-powered image generation system for Next.js with automatic fallback to placeholders.
- π€ AI Image Generation - Generate images using WaveSpeed AI (or any AI service)
- π― Centralized Configuration - Manage all images in one place
- π Automatic Fallback - Shows placeholders with prompts if images aren't generated yet
- β‘ Type-Safe - Full TypeScript support
- π Easy to Use - Simple API, works out of the box
- π¦ Framework Agnostic - Works with any Next.js project
- Copy the package to your project:
# Option 1: Download from GitHub
git clone https://github.com/yourusername/smart-image-system.git
cp -r smart-image-system/* your-project/
# Option 2: Copy files manually
# Copy lib/, components/, and scripts/ directories- Install dependencies:
npm install dotenv
npm install --save-dev tsx @types/node- Add to your
package.json:
{
"scripts": {
"generate-images": "tsx scripts/generate-all-images.ts"
}
}- Set up environment variables:
Create .env.local:
WAVESPEED_API_KEY=your_api_key_here- Configure your images:
Edit lib/image-mapping.ts:
export const imageMapping: ImageConfig[] = [
{
id: 'hero-image',
prompt: 'Beautiful sunset over mountains, professional photography',
path: 'public/images/hero.png',
aspect_ratio: '16:9',
},
];- Use in your components:
import SmartImage from '@/components/SmartImage';
export default function Hero() {
return (
<div className="relative h-screen">
<SmartImage
imageId="hero-image"
alt="Hero image"
fill
objectFit="cover"
priority
/>
</div>
);
}- Generate images:
npm run generate-imagesyour-project/
βββ lib/
β βββ image-mapping.ts # Image configuration
β βββ wavespeed.ts # AI API client
βββ components/
β βββ SmartImage.tsx # Main component
β βββ ImagePlaceholder.tsx # Fallback placeholder
βββ scripts/
βββ generate-all-images.ts # Generation script
<SmartImage
imageId="product-image"
alt="Product"
width={800}
height={600}
/><div className="relative h-64">
<SmartImage
imageId="banner-image"
alt="Banner"
fill
objectFit="cover"
/>
</div>{products.map(product => (
<div key={product.id} className="relative h-64">
<SmartImage
imageId={`product-${product.id}`}
alt={product.name}
fill
objectFit="cover"
/>
</div>
))}All images are configured in lib/image-mapping.ts:
export interface ImageConfig {
id: string; // Unique identifier
prompt: string; // AI generation prompt
path: string; // Save path (public/images/...)
component?: string; // Where it's used (optional)
aspect_ratio?: '16:9' | '1:1' | '9:16' | '4:3' | '3:4';
width?: number;
height?: number;
}interface SmartImageProps {
imageId: string; // Required: ID from image-mapping.ts
alt: string; // Required: Alt text
width?: number; // Width (if not using fill)
height?: number; // Height (if not using fill)
className?: string; // CSS classes
priority?: boolean; // Priority loading
fill?: boolean; // Fill parent container
objectFit?: 'cover' | 'contain' | 'fill' | 'none' | 'scale-down';
fallback?: boolean; // Show placeholder on error (default: true)
}- Configuration - Define images in
image-mapping.ts - Generation - Run
npm run generate-imagesto generate all images - Display - Use
<SmartImage>component in your code - Fallback - If image doesn't exist, shows placeholder with prompt
- Optimization - Uses
next/imagefor automatic optimization
Replace lib/wavespeed.ts with your AI service client:
// lib/openai.ts
import OpenAI from 'openai';
export async function generateImage(prompt: string) {
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
const response = await openai.images.generate({
model: "dall-e-3",
prompt: prompt,
});
return {
status: 'completed',
result: { image_url: response.data[0].url },
};
}Then update scripts/generate-all-images.ts to use your client.
Edit components/ImagePlaceholder.tsx to match your design system.
Get the public path for an image ID.
import { getImagePath } from '@/lib/image-mapping';
const path = getImagePath('hero-image'); // '/images/hero.png'Get full configuration for an image ID.
import { getImageConfig } from '@/lib/image-mapping';
const config = getImageConfig('hero-image');Generate a single image using WaveSpeed AI.
import { generateImage } from '@/lib/wavespeed';
const result = await generateImage('Beautiful sunset', {
aspect_ratio: '16:9',
output_format: 'png',
});- Check
WAVESPEED_API_KEYin.env.local - Verify API key is valid
- Check API rate limits
- Verify paths in
image-mapping.tsstart withpublic/ - Ensure files exist in
public/images/... - Check browser console for errors
- Ensure
fallback={true}(default) - Verify prompt is set in
image-mapping.ts
MIT License - feel free to use in your projects!
Contributions welcome! Please open an issue or pull request.
For questions or issues, please open a GitHub issue.
Made with β€οΈ for Next.js developers