Manages a two-step cover image fallback chain for entity cards: real cover URL → branded placeholder URL → `null` (hide the media element). ## Key Components ### `useCoverImageFallback(imageUrl?, placeholderUrl?)` Primary hook implementing the fallback chain. Tracks failed URLs in a `Set` so derived `src` re-resolves instantly on prop changes without reset effects or retry loops. **Returns `CoverImageFallback`:** | Field | Type | Description | |---|---|---| | `src` | `string \| null` | First non-failed URL from `[imageUrl, placeholderUrl]`, or `null` | | `onError` | `() => void` | Wire directly to the media element's `onError` handler | ### `hideOnError` Standalone event handler for compact image slots with no placeholder chain. Sets `display: none` on the broken image element, leaving the slot background visible. ## Usage Example ```typescript import { useCoverImageFallback, hideOnError } from './use-cover-image-fallback' // Full fallback chain (cover → placeholder → hide slot) function EntityCard({ coverUrl, placeholderUrl }) { const { src, onError } = useCoverImageFallback(coverUrl, placeholderUrl) if (!src) return
return Cover } // Compact card — no placeholder, just hide on break function CompactCard({ coverUrl }) { return Cover } ``` ## Design Notes - **No retry loops:** failed URLs are stored in a `Set`; once marked failed they are skipped permanently for the component's lifetime. - **Prop-change safe:** `src` is fully derived — passing a new `coverUrl` re-resolves immediately with no `useEffect` reset needed. - **Centralised logic:** replaces per-card `imageError` state and `displayImage` ternaries that previously drifted across `BlogCard` and `EntityPortraitCard`. ## Source [`use-cover-image-fallback.ts`](https://github.com/flamingo-stack/openframe-oss-lib/blob/main/use-cover-image-fallback.ts)