next-cloudinary
next-cloudinary copied to clipboard
feat: Add shimmer placeholder during AI transformation polling
Problem
When AI transformations return 423 (Locked) status during processing, broken image icons appear during polling.
PR for issue #514
Solution
Added a shimmer placeholder that displays during 423 polling:
- Hide broken icon synchronously via DOM manipulation
- Show CSS shimmer during polling
- Smooth transition when image loads
// Key change in onError handler
const img = options.target as HTMLImageElement;
img.style.opacity = '0';
img.style.visibility = 'hidden';
setIsPolling(true);
await pollForProcessingImage({ src });
setIsPolling(false);
Changes
- File:
src/components/CldImage/CldImage.tsx - Added: Shimmer placeholder with CSS animation
Testing
<CldImage removeBackground src="your-image" />
Hard refresh to see shimmer during AI processing.
Someone is attempting to deploy a commit to the Cloudinary DevX Team on Vercel.
A member of the Team first needs to authorize it.
Hi, @devpatocld. Please take a look at this.
@Vaibhav91one PR under review. Please be patient! Thank you
Yes, Absolutely @eportis-cloudinary . Thank you for the feedback. After reviewing the feedback, I wanted to discuss two approaches and would like your opinion on it.
- Render Prop Pattern (Just like in CldUploadWidget).
// Default - no changes
<CldImage
src="images/woman-headphones"
width="500"
height="500"
alt="Portrait"
/>
// With custom polling UI
<CldImage
src="images/woman-headphones"
width="500"
height="500"
alt="Portrait"
>
{({ isPolling }) => isPolling && (
<div style={{
position: 'absolute',
inset: 0,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
background: 'rgba(255, 255, 255, 0.9)'
}}>
<span>Processing...</span>
</div>
)}
</CldImage>
// Advanced - conditional styling
<CldImage
src="images/woman-headphones"
width="500"
height="500"
alt="Portrait"
>
{({ isPolling }) => (
<>
{isPolling && <Spinner size={40} />}
{isPolling && <p>AI processing in progress</p>}
</>
)}
</CldImage>
This accepts optional children function that receives isPolling boolean. User has full control over rendering logic. This matches CldUploadWidget pattern.
- Simple Prop
// Default - no changes
<CldImage
src="images/woman-headphones"
width="500"
height="500"
alt="Portrait"
/>
// With custom polling UI
<CldImage
src="images/woman-headphones"
width="500"
height="500"
alt="Portrait"
pollingFallback={
<div style={{
position: 'absolute',
inset: 0,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
background: 'rgba(255, 255, 255, 0.9)'
}}>
<span>Processing...</span>
</div>
}
/>
// With component
<CldImage
src="images/woman-headphones"
width="500"
height="500"
alt="Portrait"
pollingFallback={<Spinner />}
/>
This approach accepts optional pollingFallback prop with React component. Automatically shows/hides during polling. but there is no access to polling state for custom logic.
Hi @eportis-cloudinary @devpatocld any update on the above?
@Vaibhav91one None of these options is quite what I had in mind, but I do like them. I need to think this through, but unfortunately the time for Hacktoberfest reviews is coming to a close. I am going to mark this as accepted (without actually merging it), and you will be credited for a successful contribution. I'll and will follow up in the coming weeks about actually getting one of the patterns you identified, or somethign like them, merged. Thank you!
@Vaibhav91one None of these options is quite what I had in mind, but I do like them. I need to think this through, but unfortunately the time for Hacktoberfest reviews is coming to a close. I am going to mark this as accepted (without actually merging it), and you will be credited for a successful contribution. I'll and will follow up in the coming weeks about actually getting one of the patterns you identified, or somethign like them, merged. Thank you!
Understood @eportis-cloudinary, Let me know what to do. I will be happy to help/contribute.
@Vaibhav91one hi! we have sent you an email with the instructions for you to claim your swag price!