WebP Fallbacks with picture Element and Placeholder URLs
Use the picture element to serve WebP and AVIF with automatic webp fallback, and add placeholder URLs so every source has a usable fallback when media fails to load.
The picture element solves two different problems: format selection (serving WebP or AVIF to browsers that support it) and art direction (serving different crops at different viewport sizes). The webp fallback in the picture element's final img tag handles browsers that do not accept modern formats.
This guide covers the correct source order, how placeholder URLs fit into the picture element structure, and how to combine format fallbacks with onerror fallbacks so the image slot is never empty regardless of browser support or network failure.
Picture element basics
How the picture element handles webp fallback
The picture element contains one or more source elements followed by a mandatory img element. The browser evaluates source elements in order and uses the first one whose type and media conditions are satisfied. If no source matches, the browser falls back to the img element's src attribute.
The img element is the actual rendered element in all cases. Source elements only influence which URL is loaded. The img element's width, height, alt, class, and style attributes apply regardless of which source was selected. The onerror handler on the img element fires for failures at any source.
Source element order is important: put the most efficient format first (AVIF, then WebP) and reserve the img src for the most widely supported format (JPEG or PNG). Reversing the order causes browsers to use the less efficient format even when they support the better one.
Basic pattern
The AVIF → WebP → JPEG picture stack with webp fallback
The standard multi-format pattern puts AVIF at the top, WebP in the middle, and JPEG or PNG in the final img tag. All browsers that support AVIF use the AVIF source. Browsers that support WebP but not AVIF use the WebP source. Older browsers fall back to the img src.
Each source's srcset can contain multiple resolutions using the w descriptor. The browser picks the right resolution based on the sizes attribute and the device pixel ratio.
<picture>
<source
srcset="/image.avif 1x, /image@2x.avif 2x"
type="image/avif"
/>
<source
srcset="/image.webp 1x, /image@2x.webp 2x"
type="image/webp"
/>
<img
src="/image.jpg"
srcset="/image@2x.jpg 2x"
onerror="this.onerror=null; this.src='https://fallback.pics/api/v1/400x300/F3F4F6/9CA3AF'"
width="400"
height="300"
alt="Product photo"
loading="lazy"
/>
</picture> Placeholder sources
Adding placeholder URLs to picture source elements
When a source file does not exist yet—during development or for products without uploaded photos—a placeholder URL in the source srcset keeps the layout intact. The placeholder URL can serve any format including WebP. Use the format suffix in the fallback.pics URL to match the source element's type.
During development, replace real image URLs with placeholder URLs that match the expected dimensions. This lets you build and test the picture element structure without waiting for assets.
<!-- Development placeholder in each source -->
<picture>
<source
srcset="https://fallback.pics/api/v1/400x300.webp?text=WebP+Placeholder"
type="image/webp"
/>
<img
src="https://fallback.pics/api/v1/400x300?text=JPEG+Placeholder"
width="400"
height="300"
alt="Placeholder"
/>
</picture> Responsive sources
Combining responsive srcset with webp fallback
For responsive images, the picture element can combine format selection with responsive sizing. Use the w descriptor in srcset alongside a sizes attribute to let the browser pick both the right format and the right resolution for the current viewport and device.
Placeholder URLs can also use the w descriptor pattern by generating different sizes at build time. This is more setup than a single placeholder URL but provides an accurate preview of how the responsive image behaves at different breakpoints.
<picture>
<source
type="image/webp"
srcset="/image-400.webp 400w, /image-800.webp 800w, /image-1200.webp 1200w"
sizes="(max-width: 600px) 400px, (max-width: 960px) 800px, 1200px"
/>
<img
src="/image-800.jpg"
srcset="/image-400.jpg 400w, /image-800.jpg 800w, /image-1200.jpg 1200w"
sizes="(max-width: 600px) 400px, (max-width: 960px) 800px, 1200px"
onerror="this.onerror=null; this.src='https://fallback.pics/api/v1/800x600/F3F4F6/9CA3AF'"
width="800"
height="600"
alt="Hero image"
loading="lazy"
/>
</picture> React components
React picture component with webp fallback and onerror
In React, the picture element translates directly to JSX. Avoid the common mistake of using camelCase for srcSet—React's JSX does accept srcSet for img and source elements. The onerror handler on the img element works the same way as in plain HTML.
If you use Next.js Image component, it handles format negotiation and responsive sizes automatically via the Accept header and Cloudflare Image Resizing or a custom loader. For external images without a CDN loader, the manual picture approach is still the most reliable path.
function ResponsiveImage({ src, webp, avif, alt, width, height, fallbackSrc }) {
const [errored, setErrored] = React.useState(false);
return (
<picture>
{avif && <source srcSet={avif} type="image/avif" />}
{webp && <source srcSet={webp} type="image/webp" />}
<img
src={errored ? fallbackSrc : src}
width={width}
height={height}
alt={alt}
onError={() => !errored && setErrored(true)}
loading="lazy"
/>
</picture>
);
} Key takeaways
What to standardize before shipping
- Put source elements in order from most efficient (AVIF) to least, with the img src as the final JPEG fallback.
- The onerror handler on the img element fires for failures at any source in the picture element.
- Use format suffixes (.webp, .jpg) in fallback.pics URLs to match the type attribute in source elements.
- Combine the w descriptor for responsive sizing with type-based source selection in the same picture element.
- In React, use a state variable for errored and set the img src conditionally rather than using the string onerror attribute.
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.