Ionic and Capacitor WebView Image Fallbacks
Fix capacitor image loading failures in Ionic apps by combining ion-img error events, onerror handlers, and deterministic fallback.pics URLs across WebView environments.
Ionic apps run inside a Capacitor WebView, which means image loading behaves like a browser but with additional constraints around CORS, local file access, and mixed content policies. Capacitor image loading failures are common when remote URLs return 404s, CORS blocks requests, or the device is offline.
This guide covers the ion-img ionError event, vanilla onerror fallbacks for non-Ionic frameworks, CORS and mixed-content solutions, and pairing every failure case with deterministic fallback.pics URLs.
Problem
WebView image failures differ from browser image failures
Capacitor's WebView enforces the same CORS rules as a browser, but the origin is typically capacitor://localhost or http://localhost. Remote image hosts that do not include localhost in their Access-Control-Allow-Origin header block image loads even when the same URL works in a desktop browser.
Mixed content is another failure mode: an HTTPS Capacitor app cannot load HTTP image URLs without explicit allowMixedContent configuration in AndroidManifest.xml. These failures are silent — the image element fires an error event, but no console warning appears in the device log by default.
Using deterministic fallback.pics HTTPS URLs sidesteps both problems. The API always returns HTTPS, includes permissive CORS headers, and never blocks requests from localhost origins.
ion-img
Handling ion-img ionError for failed image loads
ion-img is Ionic's lazy-loading image component. It fires an ionError event when the src fails to load. Bind a handler to swap in a fallback URL. Avoid setting src directly inside the handler without a guard — it can trigger another error event if the fallback URL also fails.
For Angular Ionic, use event binding syntax. For React Ionic, use the onIonError prop. Both expose the same HTMLIonImgElement event object.
<!-- Angular Ionic -->
<ion-img
[src]="product.imageUrl"
[alt]="product.name"
(ionError)="onImgError($event, 400, 300)"
></ion-img>
// In component class
onImgError(event: CustomEvent, w: number, h: number): void {
const el = event.target as HTMLIonImgElement;
el.src = `https://fallback.pics/api/v1/${w}x${h}/7C3AED/FFFFFF?text=No+Image`;
el.onerror = null; // prevent loop
}
// React Ionic
<IonImg
src={product.imageUrl}
alt={product.name}
onIonError={(e) => {
const target = e.target as HTMLIonImgElement;
target.src = `https://fallback.pics/api/v1/400x300/7C3AED/FFFFFF?text=No+Image`;
(target as any).onerror = null;
}}
/> CORS
Fixing CORS and mixed content in Capacitor WebViews
For Android, add android:usesCleartextTraffic="false" and ensure your image CDN sends Access-Control-Allow-Origin: * or your app's Capacitor origin. Fallback.pics already sends permissive CORS headers so fallback images never block.
For iOS, configure NSAppTransportSecurity in Info.plist to allow only HTTPS connections. Fallback.pics serves exclusively over HTTPS, making it safe to whitelist without the NSAllowsArbitraryLoads flag.
// capacitor.config.ts — server config for image origins
{
server: {
allowNavigation: [
"fallback.pics",
"your-image-cdn.com"
]
}
}
// AndroidManifest.xml (mixed content — do not set true in production)
// <application android:usesCleartextTraffic="false" ...> Offline
Caching fallback images for offline use with Capacitor
Capacitor apps can use the Filesystem plugin to cache image blobs locally. For product catalogs with known images, pre-cache the set of fallback.pics URLs during the first launch. Ion-img will serve them from the local file system when the device is offline.
Alternatively, register a service worker that intercepts image requests and returns the cached fallback response. Service workers work in Capacitor WebViews on both iOS and Android with no additional plugin required.
Key takeaways
What to standardize before shipping
- Use ion-img's ionError event to swap in a fallback.pics URL; set onerror to null immediately to prevent an error loop if the fallback URL also fails.
- Register a document-level error listener in capture phase to catch failures from img tags inserted outside ion-img, including those from plugins and third-party libraries.
- Fallback.pics serves HTTPS with permissive CORS headers, making it safe to use as a fallback source inside Capacitor WebViews without extra configuration.
- Pre-cache fallback.pics responses with the Capacitor Filesystem plugin or a service worker to serve branded placeholders in offline mode.
- Do not set android:usesCleartextTraffic=true in production; use HTTPS fallback URLs to avoid the configuration entirely.
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.