Blur Placeholder Routes for Soft Loading States
Use fallback.pics blur placeholder URLs to create smooth soft-focus loading states that prevent layout shift and feel intentional, not broken.
A solid gray box is technically a placeholder, but it reads as broken to users. Blur placeholders use a soft, out-of-focus aesthetic that communicates "image coming" rather than "image missing," which reduces abandonment on image-heavy pages.
The fallback.pics blur route generates deterministic blurred SVGs from a URL with no client-side CSS or JavaScript required. Drop the URL into an img src and the blur state renders immediately at any dimension.
Context
Why blur placeholders outperform solid color fills
Solid color placeholders hold layout space, but they create a hard visual discontinuity when the real image loads. The eye registers the color change as a flash rather than a reveal. Blur placeholders have no sharp edge to pop because the real image and the placeholder share the same general tonal range.
There is also a legibility benefit. A blurred shape signals an image is expected rather than absent, which matters for product grids, blog hero images, and media galleries where users scan before they wait.
The tradeoff is file size. An SVG blur effect is heavier than a flat rect element. For grids with dozens of tiles, measure whether the extra bytes per placeholder affect your First Contentful Paint before committing.
Basic URL
Add a blur placeholder with one URL
The blur route accepts any width and height. The output is an SVG that uses feGaussianBlur with a base rectangle tinted to a neutral mid-gray. The blur radius scales with the smaller dimension so small thumbnails and large heroes both look appropriately soft.
Use the URL directly in an img src or as a CSS background-image. No JavaScript, no build step, no base64 encoding required.
<!-- Basic blur placeholder at 800x500 -->
<img
src="https://fallback.pics/api/v1/blur/800x500"
width="800"
height="500"
alt="Loading product photo"
/>
<!-- Smaller thumbnail in a grid -->
<img
src="https://fallback.pics/api/v1/blur/400x400"
width="400"
height="400"
alt="Loading product image"
/> Tinted blur
Match your brand with a tinted blur background
Pass a hex background color to shift the blur base from neutral gray to a brand-adjacent tone. Purple-tinted blur placeholders, for example, feel much more intentional on a purple-themed product page than generic gray.
The foreground color parameter controls the shimmer highlight layered inside the blur. Keeping it close to the background color produces a subtle effect; a higher contrast value gives a more active animated appearance.
<!-- Purple-tinted blur for a branded SaaS UI -->
https://fallback.pics/api/v1/blur/800x500/7C3AED/8B5CF6
<!-- Warm tint for a food or travel context -->
https://fallback.pics/api/v1/blur/800x500/F97316/FCD34D
<!-- Dark mode neutral blur -->
https://fallback.pics/api/v1/blur/800x500/27272A/3F3F46 React pattern
Swap blur for real image on load
The classic pattern: render the blur placeholder as the initial src, then swap in the real image URL once the asset loads. The transition is smooth because the blur and the real image share the same spatial footprint.
Use CSS opacity transition on the real image rather than instantly replacing the blur. A 200ms fade hides any resolution difference between the placeholder and the final asset.
import { useState } from 'react';
const BLUR_URL = 'https://fallback.pics/api/v1/blur/800x500';
function ProductImage({ src, alt }: { src: string; alt: string }) {
const [loaded, setLoaded] = useState(false);
return (
<div style={{ position: 'relative', width: 800, height: 500 }}>
<img
src={BLUR_URL}
width={800}
height={500}
alt=""
aria-hidden="true"
style={{ position: 'absolute', inset: 0 }}
/>
<img
src={src}
width={800}
height={500}
alt={alt}
onLoad={() => setLoaded(true)}
onError={(e) => { e.currentTarget.src = BLUR_URL; }}
style={{
position: 'absolute',
inset: 0,
opacity: loaded ? 1 : 0,
transition: 'opacity 200ms ease',
}}
/>
</div>
);
} CSS background
Use blur URLs as CSS background-image
CSS background-image works well for decorative containers where you control the box size through layout rather than the img element. Set background-size to cover to let the blur fill the container edge to edge.
This approach also works for inline styles in frameworks that accept style objects, and for server-rendered HTML where you want to avoid JavaScript altogether.
/* In a stylesheet */
.product-card__media {
background-image: url('https://fallback.pics/api/v1/blur/600x400');
background-size: cover;
aspect-ratio: 3 / 2;
}
/* Inline in a React component */
<div
style={{
backgroundImage: "url('https://fallback.pics/api/v1/blur/600x400')",
backgroundSize: 'cover',
aspectRatio: '3 / 2',
}}
/> Next.js
Blur placeholders in Next.js Image
Next.js Image accepts blurDataURL as a base64 string, but external blur URLs work just as well with the standard img fallback pattern or a plain img element inside a Next.js page. For App Router with server components, fetch the blur URL string and pass it as the src before the real image resolves.
If you use next/image and want the built-in blur effect, you can still use fallback.pics for error states: the onError handler fires when the primary src fails, letting you swap in the blur URL as a controlled broken-image fallback.
// pages/ProductCard.tsx – error fallback with blur URL
'use client';
import Image from 'next/image';
const BLUR = 'https://fallback.pics/api/v1/blur/800x500';
export function ProductCard({ src, alt }: { src: string; alt: string }) {
return (
<Image
src={src}
alt={alt}
width={800}
height={500}
onError={(e) => {
e.currentTarget.src = BLUR;
}}
/>
);
} Performance note
Cache and CDN behavior for blur SVGs
Blur SVGs are generated deterministically from the URL parameters. The same URL always returns the same bytes, so CDN caching is safe with a long max-age. Set Cache-Control: public, max-age=31536000, immutable for production workloads.
For grids with many identical-dimension tiles, browsers will cache the first blur response and reuse it for all subsequent img tags pointing to the same URL. One network round-trip covers the entire grid.
# Verify caching headers
curl -I "https://fallback.pics/api/v1/blur/400x400"
# Internal links for deeper reading
# https://fallback.pics/docs/
# https://fallback.pics/placeholder-image-api/
# https://fallback.pics/blog/skeleton-placeholder-images-vs-static-fallbacks/
# https://fallback.pics/blog/prevent-layout-shift-missing-images/ Key takeaways
What to standardize before shipping
- Blur placeholders feel intentional; solid gray boxes feel broken.
- The /blur/ route generates deterministic SVGs from a URL with no client JavaScript.
- Tint the blur with hex color parameters to match your brand palette.
- Fade from blur to real image with a CSS opacity transition, not an instant swap.
- One blur URL is cached by the browser for all tiles sharing that dimension.
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.