HTML download Attribute
The HTML download attribute specifies that the target will be downloaded when clicking on the hyperlink. Read and find out on what elements it can be used.
The HTML download attribute tells the browser to download the linked resource as a file instead of navigating to it. By default, clicking a link to a PDF, image, or text file opens it in the browser; adding download forces a "Save as" download instead. You add it to a hyperlink, and you can optionally give it a value to suggest a filename for the saved file.
When would you use it? Reach for download when the link points to a file the user should keep rather than view — a PDF report, a generated CSV export, an image saved from a <canvas>, a ZIP archive, or any "save this" action. It is used only if the href attribute is set.
You can use the download attribute on the following elements: <a> and <area>.
Suggesting a filename
The value of the attribute specifies the name of the downloaded file. The browser uses the value exactly as typed, without automatically adding a file extension — so include the extension yourself. If the value is omitted, the browser falls back to the original filename from the URL (or one inferred from the response).
<!-- Saves with the server's original filename -->
<a href="/files/2024-q4-9f8a7b.pdf" download>Download report</a>
<!-- Overrides the filename: saves as "report.pdf" -->
<a href="/files/2024-q4-9f8a7b.pdf" download="report.pdf">Download report</a>The filename override is especially handy when your server stores files under hashed or cryptic names but you want the user to receive a friendly, readable filename.
Syntax
<a href="url" download="filename">link text</a>The filename value is optional. <a href="url" download> works too and keeps the original name.
Example of the HTML download attribute used on the <a> element:
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
</head>
<body>
<h1>Click on the logo to download it:</h1>
<p>
<a href="/uploads/media/default/0001/01/0710cad7a1017902166203def268a0df2a5fd545.png" download="w3docs-logo.png">
<img src="/uploads/media/default/0001/01/0710cad7a1017902166203def268a0df2a5fd545.png" alt="W3Docs" width="190" height="45" />
</a>
</p>
</body>
</html>The same-origin restriction
This is the most common reason download "doesn't work." For security reasons, the download attribute is only honored for:
- Same-origin URLs — the file is served from the same scheme, host, and port as the current page.
blob:URLs — created in JavaScript withURL.createObjectURL().data:URLs — inline data encoded directly in thehref.
For a cross-origin URL (a file hosted on another domain), the attribute is ignored: the browser simply navigates to the resource as if download weren't there. The filename override is also dropped. So <a href="https://other-site.com/file.pdf" download="report.pdf"> will not save report.pdf — it just opens the remote file.
Workaround: fetch the file and create a blob URL
To force a download of a cross-origin file (assuming the remote server allows it via CORS), fetch it into memory, wrap it in a blob URL, and trigger a download with that:
<button id="dl">Download remote PDF</button>
<script>
document.getElementById('dl').addEventListener('click', async () => {
const response = await fetch('https://other-site.com/file.pdf');
const blob = await response.blob();
const blobUrl = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = blobUrl;
a.download = 'report.pdf'; // honored, because blob: is allowed
document.body.appendChild(a);
a.click();
a.remove();
URL.revokeObjectURL(blobUrl); // free the memory
});
</script>The remote server must send permissive CORS headers (for example Access-Control-Allow-Origin: *) for the fetch to succeed.
Generating downloads with data: URLs
Because data: URLs are same-origin by definition, you can download content created entirely in the browser without any server round-trip — useful for CSV exports or saving a <canvas> drawing as an image:
<a id="csv" download="export.csv">Download CSV</a>
<canvas id="c" width="100" height="100"></canvas>
<a id="img" download="drawing.png">Save drawing</a>
<script>
// 1. A generated CSV file
const csv = 'Name,Score\nAlice,90\nBob,85';
document.getElementById('csv').href =
'data:text/csv;charset=utf-8,' + encodeURIComponent(csv);
// 2. A canvas saved as a PNG (toDataURL returns a data: URL)
const canvas = document.getElementById('c');
document.getElementById('img').href = canvas.toDataURL('image/png');
</script>For larger files, prefer the blob-URL approach over data: URLs, since very long data: strings are memory-heavy and some browsers cap their length.
Using download on an image map area
The download attribute also works on the <area> element inside an image map, so individual clickable regions of an image can each download a different file.
Example of the HTML download attribute used on the <area> element:
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
</head>
<body>
<p>Click on one of the HTML, CSS or PHP logo and download it:</p>
<img src="/uploads/media/news_gallery/0001/01/thumb_316_news_gallery_list.jpeg" width="250" height="150" alt="block" usemap="#blockmap" />
<map name="blockmap">
<area shape="circle" coords="50,32,25" alt="html" href="/uploads/media/book_gallery/0001/01/d450f0358f947dffb3af91195c3002600d74101b.png" download />
<area shape="circle" coords="218,115,25" alt="css" href="/uploads/media/book_gallery/0001/01/25521e981b34da57c8f51baddc5b76351b855818.png" download />
<area shape="circle" coords="195,32,28" alt="php" href="/uploads/media/book_gallery/0001/01/4bbee6698c4884f25c46010d61b658dd62d2c04f.png" download />
</map>
</body>
</html>