Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Put the <img> element inside an <a> element. Set the anchor’s href to the image or destination you want opened, and add the download attribute when you want the browser to request a file download.

src controls the image shown on the page; href controls what happens when the image is activated. They can point to the same file or to different files.

Choose the result you want

“Save an image with a link” can mean two different interactions. Decide whether the click should open a resource or request that it be saved locally.

Intent Markup Expected result
Open the original image or another page <a href="destination"><img src="thumbnail" alt="..."></a> The browser follows the anchor’s href.
Request a download <a href="file" download="suggested-name.ext"><img src="thumbnail" alt="..."></a> The browser is asked to save the resource instead of treating the click as ordinary navigation.

The download attribute is a request, not a guarantee. Browser policies, user settings, the response headers, and the relationship between the page and the file’s origin can change the final behavior.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Make the image itself clickable

For a normal image link, nest the image in an anchor and omit download:

<a href="/images/photo-original.jpg">
  <img src="/images/photo-thumbnail.jpg" alt="View the full-size sunset photo">
</a>

Here, the visitor sees photo-thumbnail.jpg. Activating it requests /images/photo-original.jpg. The alt text describes the link’s destination, so someone who cannot see the image still understands the action.

If the displayed image is also the file to open, use the same URL in both attributes:

<a href="photo.jpg">
  <img src="photo.jpg" alt="View the full-size photo">
</a>

The anchor’s href is the important part for navigation. Changing only src changes the preview, not the link target.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Request that the image be downloaded

Add download to the anchor. You may leave it empty or provide a suggested filename:

Rank #2
Sale
HTML and CSS: Design and Build Websites
  • HTML CSS Design and Build Web Sites
  • Comes with secure packaging
  • It can be a gift option
<a href="photo.jpg" download="holiday-photo.jpg">
  <img src="photo.jpg" alt="Download the holiday photo">
</a>

A value such as holiday-photo.jpg suggests the name shown in a save dialog or used for an automatic save. Without a value, the browser may derive a name from the server’s response, the URL path, or the media type.

Use a different preview when the full-resolution file is large:

<a href="/downloads/company-logo.svg" download="company-logo.svg">
  <img src="/images/company-logo-256.png" alt="Download the company logo as an SVG file">
</a>

The visitor sees a PNG thumbnail but receives the SVG requested by href. Make the alternative text describe the action and file type rather than merely repeating a visual label.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What the browser can and cannot guarantee

Same-origin, blob, and data URLs

Browser support for download is defined for same-origin URLs and for blob: and data: URLs. If the page and image are served from the same origin, the attribute is the straightforward solution:

<a href="/assets/report-cover.png" download="report-cover.png">
  <img src="/assets/report-cover.png" alt="Download the report cover image">
</a>

“Same origin” means the scheme, host, and port match. A page at https://example.com and a file at https://cdn.example.com are different origins even though they share a parent domain.

Cross-origin files

Do not promise a download merely because download appears in the HTML. For a cross-origin resource, the HTML Standard’s downloading rules require server-side cooperation: the response should include a Content-Disposition header with an attachment disposition. Configure that on the server that delivers the file, for example:

Content-Disposition: attachment; filename="holiday-photo.jpg"

The server’s filename parameters can override the filename suggested by the HTML attribute. If you do not control the other origin, you cannot reliably force its response to download; link to it normally or provide a same-origin copy that you are allowed to distribute.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Opening, prompting, or saving

Browsers and user preferences decide whether the resource is saved automatically, a save dialog appears, or the file opens in the browser or an external application. Treat download as an instruction to try a download, not as a silent-save API. Test the actual browser and deployment environment your visitors use.

Write accessible linked-image markup

A linked image needs useful alternative text. The wording should communicate the destination or action, just as visible link text would:

  • For navigation, use text such as View the full-size product photo.
  • For a file transfer, use text such as Download the product photo as a JPEG.
  • Do not use vague text such as image when the click performs a specific action.

Keep the alt value concise, and do not repeat surrounding visible text unnecessarily. If the image is purely decorative but the link has a meaningful action, the alternative text still needs to name that action.

Reliable patterns you can copy

Open a full-size image

<a href="/gallery/mountain-large.jpg">
  <img src="/gallery/mountain-small.jpg" alt="View the full-size mountain photograph">
</a>

Download the displayed image

<a href="/gallery/mountain.jpg" download="mountain.jpg">
  <img src="/gallery/mountain.jpg" alt="Download the mountain photograph">
</a>

Download a different file than the preview

<a href="/downloads/catalog.pdf" download="catalog.pdf">
  <img src="/images/catalog-cover.jpg" alt="Download the product catalog PDF">
</a>

In every example, verify that the URL in href is reachable and that the suggested extension matches the file actually returned. A misleading extension can cause confusing names or incorrect application associations.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Troubleshoot a link that opens instead of downloading

The download attribute is missing or misspelled

Inspect the rendered HTML and confirm that download is on the <a> element, not on <img>. The correct spelling is lowercase download.

The URL is cross-origin

Check the scheme, host, and port of the page and file. If they differ, configure the file response with Content-Disposition: attachment, or serve an authorized copy from your own origin.

The server supplies a different filename

Inspect the response headers. A server-provided filename or filename* can replace the value in download. Change the server configuration if the delivered name is wrong.

The browser opens the image anyway

This can be normal. Browser implementation and user settings affect whether a download prompt appears or the media opens. Try the same link in the browsers you support and explain the expected action in the alt text or nearby visible text.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The click does nothing or returns an error

  • Open the href directly in a new tab to check for a 404, authorization failure, or redirect.
  • Confirm that relative paths are resolved from the page’s URL, not from your project folder.
  • Check that URL characters are properly encoded and that the file extension and MIME type match the resource.
  • If a login or expiring URL is required, generate the link on the server and make sure it remains valid long enough for the click.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Security and delivery checks

Only offer files that the current visitor is authorized to receive. A download link is not an access-control mechanism: anyone who obtains the href may try it directly. For private images, enforce authorization when the server handles the request and use short-lived URLs where appropriate.

Keep the anchor destination and the visible description aligned. If the thumbnail says “download” but the link opens a login page or a different file, visitors and assistive-technology users receive misleading feedback.

Or skip the browser setup

If you need to create the image file first, ScreenshotNeo can capture a URL through one GET request. It is a website screenshot API and MCP server for developers. Before capture, it accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and each response identifies the result with X-Page-Verdict and X-Billed headers.

After you save the returned PNG, JPEG, or WebP and host it at a URL your page can reach, use that URL as the anchor’s href or src. ScreenshotNeo also supports PDF output, element captures, custom CSS and JavaScript, device and viewport settings, lazy-image loading, signed links for public <img> tags, asynchronous jobs, bulk capture of up to 100 URLs per call, and an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

See the ScreenshotNeo website and API documentation for parameter details. The same request can be made from common environments:

cURL

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Python

import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)

Node.js

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

There is a free allowance of 1,000 screenshots per month without a card. Paid plans start at $5 for 3,000 shots; yearly billing provides two months free, and every feature is available on every plan. Create a free ScreenshotNeo account to get started.

Final checklist

  • Wrap the image in an <a> element.
  • Put the file or destination URL in href.
  • Add download only when a save request is the intended action.
  • Use a value such as download="photo.jpg" when a suggested filename helps.
  • Check same-origin restrictions and configure Content-Disposition: attachment for cross-origin downloads you control.
  • Write alt text that names the destination or download action.
  • Test the delivered response, filename, and browser behavior before publishing.

Frequently Asked Questions

Can the thumbnail and downloaded file be different?

Yes. Set the thumbnail URL in src and the file to open or download in the anchor’s href.

Does adding a filename to download force that exact name?

No. It is a suggested filename. A server’s Content-Disposition filename and the browser’s handling can take precedence.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.