supportsWebP
Checks if the browser supports WebP image format.
1/**
2 * Checks if the browser supports WebP image format.
3 *
4 * @returns A promise that resolves to true if WebP is supported, false otherwise.
5 */
6export function supportsWebP(): Promise<boolean> {
7 if (typeof window === 'undefined') return Promise.resolve(false);
8
9 return new Promise(resolve => {
10 const img = new Image();
11 img.onload = () => resolve(img.width === 1);
12 img.onerror = () => resolve(false);
13 img.src =
14 'data:image/webp;base64,UklGRiIAAABXRUJQVlA4TAYAAAAvAAAAAAfQ//73v/+BiOh/AAA=';
15 });
16}
Lightweight Detection Mechanism
Uses a tiny base64-encoded WebP image to test support, minimizing performance impact and bandwidth.
Asynchronous and Non-Blocking
Returns a Promise, allowing seamless integration into modern async workflows without blocking UI rendering.
Cross-Browser Safe
Performs a runtime check rather than relying on user agent sniffing, ensuring accurate detection across browsers and versions.
Failsafe Fallback
Gracefully resolves to
false
on image load failure, ensuring no exceptions or crashes in unsupported environments.Server-Side Rendering Aware
Includes a check for
window
to prevent runtime errors when executing in SSR or non-browser contexts.
Tests | Examples
1const originalImage = global.Image;
2
3afterEach(() => {
4 global.Image = originalImage;
5});
6
7test('resolves to true when WebP image loads successfully', async () => {
8 class MockImage {
9 width = 1;
10 onload: () => void = () => {};
11 onerror: () => void = () => {};
12 set src(_: string) {
13 setTimeout(() => this.onload(), 0);
14 }
15 }
16 // @ts-expect-error: override Image for test
17 global.Image = MockImage;
18 await expect(supportsWebP()).resolves.toBe(true);
19});
20
21test('resolves to false when WebP image fails to load', async () => {
22 class MockImage {
23 width = 0;
24 onload: () => void = () => {};
25 onerror: () => void = () => {};
26 set src(_: string) {
27 setTimeout(() => this.onerror(), 0);
28 }
29 }
30 // @ts-expect-error: override Image for test
31 global.Image = MockImage;
32 await expect(supportsWebP()).resolves.toBe(false);
33});
34
35test('resolves to false in non-browser environments', async () => {
36 const originalWindow = globalThis.window;
37 // @ts-expect-error
38 delete globalThis.window;
39 await expect(supportsWebP()).resolves.toBe(false);
40 globalThis.window = originalWindow;
41});
Common Use Cases
Conditional Image Loading
Dynamically load WebP assets if supported, or fallback to JPEG/PNG for broader compatibility.
Performance Optimization
Serve more efficient WebP images to reduce load times and bandwidth usage in modern browsers.
Feature Detection in Progressive Enhancement
Inform rendering logic or asset bundlers whether to apply WebP-specific optimizations.
Content Delivery Strategy
Customize image delivery in CDNs or image services based on support status.