Vercel Image Optimization vs External Placeholder APIs
Vercel's built-in image optimization transforms real media at the edge. External placeholder APIs handle missing or blank images. Here is how to use both together.
Vercel Image Optimization — exposed through Next.js's next/image component — resizes, compresses, and converts real image assets to WebP and AVIF at the edge. It is excellent at what it does, but it requires a real image to optimize. When an image is missing, the URL is null, or the asset returns a 404, next/image shows a broken image.
External placeholder APIs fill the gap that Vercel Image Optimization does not cover: generating a visible, correctly sized image from nothing but a URL. The practical setup is to use next/image for real assets and fall back to a placeholder URL when the image source is absent or broken.
What Vercel handles
Vercel Image Optimization pipeline: resize, convert, cache
When you use next/image with a src pointing to a real image, Vercel processes the original asset the first time a specific size is requested. It resizes the image to the requested width, converts it to WebP or AVIF based on the browser's Accept header, applies quality compression, and caches the result at the edge.
Subsequent requests for the same URL and width combination are served from cache with near-zero latency. The original heavy JPEG upload from your CMS becomes a compact WebP served from a CDN edge within 20ms. This pipeline is designed for real image assets — photos, user uploads, product photography.
Vercel Image Optimization has limits: a free plan allows 1,000 images per month. Exceeding this triggers 429 errors or charges depending on your plan. For a product catalog with 10,000 SKUs, optimizing every product image through Vercel's pipeline on the first request can exhaust the free tier quickly.
The gap
What next/image does not handle: missing and null sources
next/image requires a non-empty src prop. If your data layer returns null for an image field, you cannot pass null to next/image's src without a runtime error. You must either guard the component with a conditional render or provide an alternative src value.
When next/image receives a 404 from its src URL, it renders a broken image icon — the same as a raw img tag. The optimization pipeline does not generate a fallback or return a placeholder. Error handling is the application's responsibility.
This is the exact use case for external placeholder APIs. Use a placeholder URL as the fallback src when the image field is null or empty. When the optimized image source fails to load, use an onerror handler to swap the src to a placeholder URL.
Integration pattern
Using next/image with a fallback.pics placeholder src
The cleanest Next.js pattern is a thin wrapper component around next/image that handles null src and load errors. The wrapper receives the optional image src and a fallback URL, uses the fallback when the src is absent, and swaps to the fallback on error.
Pass the placeholder URL through next/image's src prop rather than bypassing next/image with a raw img tag. This keeps the optimization pipeline active for real images while falling back to the placeholder URL for missing ones.
import NextImage from 'next/image';
interface OptimizedImageProps {
src?: string | null;
alt: string;
width: number;
height: number;
className?: string;
}
export function OptimizedImage({ src, alt, width, height, className }: OptimizedImageProps) {
const fallback = `https://fallback.pics/api/v1/${width}x${height}/7C3AED/FFFFFF?text=Image`;
const [imgSrc, setImgSrc] = React.useState(src || fallback);
return (
<NextImage
src={imgSrc}
alt={alt}
width={width}
height={height}
className={className}
onError={() => setImgSrc(fallback)}
unoptimized={!src} // skip Vercel optimization for placeholder URLs
/>
);
} unoptimized prop
Skip Vercel optimization for external placeholder URLs
next/image with an external src URL requires that domain to be listed in next.config.js under images.remotePatterns. If you add fallback.pics as an allowed domain, Vercel will attempt to optimize placeholder URLs through its pipeline — adding latency and consuming optimization quota for content that does not need optimization.
Use the unoptimized prop on next/image when the src is a placeholder URL. This tells Vercel not to route the request through the image optimization service and instead serve it as a direct passthrough. You avoid quota usage and the optimization overhead for simple placeholder images.
A practical approach is to check whether the src is a placeholder domain and set unoptimized accordingly, or to always pass unoptimized when the component renders a fallback state.
Performance comparison
Latency: Vercel-optimized image vs direct placeholder URL
Vercel-optimized images are served from Vercel's edge CDN after the first optimization pass. Once cached, they are as fast as any CDN-served image — 10–30ms from nearby edges. The first request for a new size combination hits the origin, which can take 200–800ms for large images.
fallback.pics placeholder images are generated at a Cloudflare Worker edge node and cached with immutable headers. The first request for a placeholder URL takes 10–50ms (Worker compute). Cached requests return in 5–15ms. For placeholder use cases, the latency is comparable to Vercel's cached response.
The meaningful performance difference is in the optimization pipeline for real images. Vercel converts a 5MB JPEG upload to an 80KB WebP. A placeholder API has no equivalent input — it generates content from parameters. These are complementary tools for different problems.
Cost considerations
Vercel image quota vs placeholder API cost model
Vercel's free plan includes 1,000 optimized image units per month. Pro includes 5,000. Each unique image+size combination counts as one unit. For an ecommerce catalog with 5,000 products and three size breakpoints, that's 15,000 optimizations — already over the Pro plan's included quota.
fallback.pics placeholder images are not counted against Vercel's image optimization quota when served with unoptimized=true or as external URLs. The cost model for the placeholder API is separate and independent of Vercel's billing.
# Vercel next.config.js: allow fallback.pics as external image domain
# module.exports = {
# images: {
# remotePatterns: [
# { protocol: 'https', hostname: 'fallback.pics' }
# ]
# }
# }
# API docs
https://fallback.pics/docs/
https://fallback.pics/placeholder-image-api/
# Related posts
https://fallback.pics/blog/nextjs-image-fallbacks-without-layout-shift/
https://fallback.pics/blog/netlify-image-cdn-fallbacks/ Key takeaways
What to standardize before shipping
- Vercel Image Optimization handles real asset compression and format conversion; it does not generate placeholders for missing sources.
- Use next/image with unoptimized=true when the src is a placeholder URL to avoid wasting Vercel optimization quota.
- Build a thin wrapper component that accepts an optional src and falls back to a placeholder URL when the image is null or fails to load.
- Both systems use CDN edge caching — performance is comparable once both are warmed up.
- Vercel and external placeholder APIs are complementary tools: optimization for real assets, generation for missing ones.
Production fallback layer
Use fallback.pics anywhere an image URL is accepted.
Start with one deterministic URL and standardize fallback behavior across your design system.