adaptive_network_image 0.1.2
adaptive_network_image: ^0.1.2 copied to clipboard
A Flutter widget that displays images from external URLs on web, handling CORS restrictions with a multi-strategy fallback approach.
adaptive_network_image #
A Flutter package built primarily for web, solving CORS restrictions when loading external images. It uses a multi-strategy fallback approach that works across all browsers. On non-web platforms (Android, iOS, macOS, Windows, Linux), it uses Flutter's default Image.network -- no extra setup needed.
How It Works #
AdaptiveNetworkImage tries up to three strategies in order until one succeeds:
- directImg -- Renders an HTML
<img>element viaHtmlElementView. Lightest approach; works when the server sends appropriate CORS headers. - corsProxy -- Fetches image bytes through a CORS proxy, then displays via
Image.memory. Requires acorsProxyUrlto be provided. Skipped otherwise. - iframe -- Renders the image inside a sandboxed
<iframe>with no inline scripts. Heaviest approach but most compatible.
The first strategy that loads successfully is used. Resolved strategies are cached so subsequent renders skip straight to what worked.
Quick Start #
flutter pub add adaptive_network_image
import 'package:adaptive_network_image/adaptive_network_image.dart';
AdaptiveNetworkImage(
imageUrl: 'https://example.com/photo.jpg',
width: 300,
height: 200,
fit: BoxFit.cover,
)
Configuration #
| Parameter | Type | Default | Description |
|---|---|---|---|
imageUrl |
String |
required | URL of the image to display. |
width |
double? |
null |
Fixed width constraint. |
height |
double? |
null |
Fixed height constraint. |
fit |
BoxFit |
BoxFit.cover |
How the image fits within its bounds. |
placeholder |
WidgetBuilder? |
null |
Builder for a widget shown while loading. Defaults to a CircularProgressIndicator. |
errorWidget |
AdaptiveImageErrorBuilder? |
null |
Builder for a widget shown when all strategies fail. Defaults to a broken-image icon. |
fadeInDuration |
Duration |
300ms |
Duration of the fade-in animation. |
fadeInCurve |
Curve |
Curves.easeIn |
Curve of the fade-in animation. |
borderRadius |
BorderRadius? |
null |
Clips the image with the given border radius. |
headers |
Map<String, String>? |
null |
HTTP headers sent with image requests. |
corsProxyUrl |
String? |
null |
CORS proxy base URL. The image URL is appended (encoded). Required for the corsProxy strategy. |
onTap |
VoidCallback? |
null |
Callback invoked when the image is tapped. |
enableCache |
bool |
true |
Whether to cache strategy resolution and image bytes. |
strategies |
List<ImageLoadStrategy>? |
null |
Ordered list of strategies to attempt. Defaults to all three. |
onStrategyResolved |
ImageLoadCallback? |
null |
Callback invoked when a strategy successfully loads the image. |
preventNativeInteraction |
bool |
true |
Prevents native browser interactions (drag, right-click) on web HTML elements. |
Strategy Trade-offs #
| Strategy | Weight | Requires | Notes |
|---|---|---|---|
directImg |
Lightest | Server CORS headers | Best performance; may fail if the server blocks cross-origin requests. |
corsProxy |
Medium | corsProxyUrl |
Full pixel access via Image.memory; adds a proxy hop. |
iframe |
Heaviest | Nothing | Always works, but creates a sandboxed iframe per image. |
You can restrict or reorder strategies:
AdaptiveNetworkImage(
imageUrl: url,
strategies: [ImageLoadStrategy.corsProxy, ImageLoadStrategy.iframe],
corsProxyUrl: 'https://my-proxy.example.com/',
)
Platform Support #
| Platform | Behavior |
|---|---|
| Web (all browsers) | Multi-strategy CORS handling (directImg, corsProxy, iframe). |
| Android / iOS | Uses Flutter's default Image.network. |
| macOS / Windows / Linux | Uses Flutter's default Image.network. |
You can use AdaptiveNetworkImage as a drop-in replacement for Image.network across all platforms. On web it handles CORS automatically; everywhere else it delegates to Flutter's built-in image loading.
Cache #
Image bytes and resolved strategies are cached in an LRU cache with byte-based eviction. To clear the cache manually:
AdaptiveNetworkImage.clearCache();
Disable caching per widget with enableCache: false.
Logging #
Enable debug logging to diagnose CORS issues:
adaptiveImageLogging = true;
Logs are printed via debugPrint and are off by default.
License #
MIT -- see LICENSE for details.