HTML download attribute not working with external image URLs

I’m trying to make a simple download button for images using the HTML5 download attribute. The problem is that it works sometimes but not always.

I found a tutorial that shows a working example, but when I try to use different image URLs, the download doesn’t start. Instead of downloading the file, it just opens the image in the browser.

Here’s what I’m trying to do:

<a href="https://example.com/path/to/some-artwork.jpg" download="my-image.jpg">
  <button>Download Image</button>
</a>

This code should trigger a download when clicked, but it doesn’t work with external URLs. The same approach works fine with local files on my server. What am I missing here? Is there something special about how the download attribute handles different domains?

Been dealing with this exact headache for years. CORS restrictions make the download attribute useless for external images.

I skip the custom server endpoints and blob URL mess entirely. Just automate it - set up a workflow that watches for download requests, grabs external images through a proxy, and serves them with proper headers.

You get bulk downloads, image processing, and caching for popular images. No browser security fights.

Our design team constantly pulls assets from different CDNs with this method. Works perfectly and scales great.

yup, def a CORS thing. browsers are strict about cross-origin stuff. that download attr doesn’t work with external URLs for security. you might wanna fetch the image via your server or use a proxy to make it work.

The download attribute won’t work with external domains because of same-origin policy restrictions. Browsers treat cross-domain image links as navigation, not downloads, for security reasons. I ran into this exact problem building a gallery site last year. My workaround was creating a server endpoint that fetches the external image and serves it with Content-Disposition: attachment headers. You can also use JavaScript to fetch the image as a blob, create an object URL, and trigger the download programmatically. This bypasses the cross-origin issue since you’re downloading from your own origin.