html-to-image: Image is displayed in browser, but doesn't come through with download (Safari)
Expected Behavior
I’m trying to download html including an img tag using safari, but the source doesn’t show up, just an empty div.
Current Behavior
I have a preview box:
function Preview() {
const mobileRef = useRef(null);
const download = () => {
setIsLoading(true);
toPng(mobileRef.current, {})
.then((dataUrl) => {
const link = document.createElement("a");
link.download = "youtube.png";
link.href = dataUrl;
link.click();
setIsLoading(false);
})
.catch((err) => {
console.log(err);
});
};
return (
<div>
<div ref={mobileRef}>
<img src={img} alt="" />
</div>
<button onClick={download}>DOWNLOAD</button>
</div>
)
}
When I download the image I get all the html besides the picture; instead just an empty div. where the image should be. All other parts of the html convert and download as a PNG, so I’m confused as to why the only issue is converting the img, especially when the img is being displayed in the browser. I’m wondering if this is a react issue, or just an issue with downloading images of an img.
Possible Solution
I’m not sure what’s causing this, maybe it’s an issue with my set up or css, but it doesn’t really make sense to me. Someone mentioned in the comments that it may be an issue with CORS; I checked the network tab on safari when I hit download and there are a few things that come up:
The bottom is the png file (my static file) that is displayed in the browser but not when I download the html. Here it is displayed as a png, headers read 200, status okay.
Next up is an svg of the entire downloaded html. Inside the network tab, the svg file shows everything even the static png that doesn’t show up in the downloaded html-to-image. Headers also read 200.
Next is an xhr, looks the same as the first png. Also 200.
The top 3 are all 304 not modified.
I’m pretty new to coding so all of this doesn’t really make a lot of sense to me.
Steps To Reproduce
Best way to reproduce this is to just use the code example I gave and replace the src with any photo you have locally or online. I tried downloading with local photos and with google photos/gifs online and both ways come back with an empty div. I think it’s important to state again that the images are displaying in the safari browser, they just don’t get converted from html to PNG.
Your Environment
Since this is only happening to me in safari, I can’t help but think it’s not an issue with my code. Of course it could be – I am setting my img with a react setState and having the src={require('')} but again, since the img displays in the browser, I can’t help but think it’s just a bug. Would love to help more, just not really sure what’s causing the issue.
- html-to-image: 1.11.2
- OS: macOS Monteray 12.6
- Browser: chrome (108.0.5359.98) but also safari.
About this issue
- Original URL
- State: open
- Created 2 years ago
- Reactions: 6
- Comments: 32 (1 by maintainers)
I am facing a similar issue, I tested the library with Chrome on iOS, and The behaviour is the same as safari on iOS. The issue is only on iPhone. as I tested with Android, and Desktop, I got good results.
If anyone has a fix for it, I would greatly appreciate it. 👍🏻
Same issue. The image is lost after downloading.
Bug appears in safari on iPhone and desktop.
Hello Yehuda! We faced the same issue, and it turned out to be a cors error with our image server. checkout the network Tab to see if that’s the case. If it is, we solved it through the server configuration.
Hope it helps!
Thanks your solution worked with me. Another way might help is to download the image before add it to the dom that being converted into an image.
I have the same issue with iphone mobile, the android mobile and pc browser web are all normal.
@minusmo I replaced this library with the html2canvas. what I did is rendered the content on the page by inserting the dynamically generated content then I called the method to convert data to base64 image. once image is generated I removed the content from page that I added previously programmatically.
The implementation really depends on the usecase. and I found that if content is available on the page (not dynamic content) then these libraries works well.
I am not sure what that error means exactly as I tested it in Chrome browser and it shows a CORS error. Maybe you should checkout if that error is related to CORS. When I talk about server configuration I mean proxy headers. We realized it was our server problem because internet images (for example from google images) loaded correctly. You could do the same test to discard this problem