download
Triggers a file download instead of navigating to the URL. Optionally suggests a filename for the saved file.
Overview
The download attribute on <a> and <area> elements tells the browser to download the linked resource as a file instead of navigating to it. Without this attribute, the browser decides based on the MIME type — PDFs might open in a viewer, images display inline, and HTML navigates.
When a value is provided, it serves as the suggested filename for the download. The user can still change the name in the save dialog.
Values
| Usage | Behavior |
|---|---|
download (no value) | Download the file using the filename from the URL |
download="name.ext" | Suggest a custom filename for the download |
Applies to: <a>, <area>
<!-- Download instead of navigating (uses the URL's filename) --><a href="/files/annual-report.pdf" download>Download Report</a> <!-- Suggest a custom filename --><a href="/files/report-2024-q4-final-v3.pdf" download="annual-report.pdf"> Download Report</a> <!-- Works on <area> elements too --><map name="downloads"> <area shape="rect" coords="0,0,100,50" href="/files/brochure.pdf" download="brochure.pdf" alt="Download brochure" /></map>
Cross-Origin Limitation
For security reasons, the download attribute is ignored on cross-origin URLs. If the link points to a different origin, the browser navigates to the URL instead of downloading. This prevents a malicious page from silently downloading files from other domains onto the user's device.
<!-- Same-origin: download works as expected --><a href="/files/data.csv" download="export.csv">Export CSV</a> <!-- Cross-origin: browser IGNORES the download attribute and navigates instead --><a href="https://other-site.com/files/data.csv" download="export.csv"> This will navigate, not download</a>
To enable cross-origin downloads, the server must set the Content-Disposition: attachment HTTP header. This is a server-side solution that works regardless of the download attribute.
Generated Content with Blob URLs
The most powerful use of download is with Blob URLs for client-generated content. Create the data in JavaScript, wrap it in a Blob, generate a temporary URL, and trigger a download — no server round-trip required.
<button id="export-btn">Export Data as JSON</button> <script>document.getElementById('export-btn').addEventListener('click', () => { const data = { users: 142, active: 98, date: new Date().toISOString() }; const json = JSON.stringify(data, null, 2); const blob = new Blob([json], { type: 'application/json' }); const url = URL.createObjectURL(blob); const link = document.createElement('a'); link.href = url; link.download = 'export.json'; link.click(); URL.revokeObjectURL(url);});</script>
Canvas to Image Download
Combine download with canvas.toDataURL() to let users save canvas drawings as image files.
<canvas id="chart" width="400" height="300"></canvas><a id="save-chart" download="chart.png">Save Chart as PNG</a> <script>const canvas = document.getElementById('chart');const link = document.getElementById('save-chart');// After drawing on the canvas...link.href = canvas.toDataURL('image/png');</script>
Filename Behavior
- If
downloadhas no value, the browser derives the filename from the URL path (e.g./files/report.pdfsaves asreport.pdf). - If a value is provided, it overrides the URL-derived name but the server's
Content-Dispositionheader takes priority over both. - The browser may sanitize the suggested filename, stripping path separators and other unsafe characters.
- For Blob URLs, there is no URL-derived name, so providing a
downloadvalue is essential.
Security Considerations
The cross-origin restriction exists to prevent drive-by downloads from untrusted origins. Even for same-origin resources, browsers may prompt the user before downloading executable file types (.exe, .bat, .sh). Some browsers block downloads entirely from sandboxed iframes unless allow-downloads is present.
Limitations
- Cross-origin URLs ignored: The attribute has no effect when the href points to a different origin. Use server-side
Content-Dispositionheaders instead. - No progress feedback: There is no built-in way to show download progress for
download-triggered downloads. Large files start downloading silently. - Content-Disposition wins: If the server sends a
Content-Dispositionheader, its filename takes priority over thedownloadattribute value. - Data URL size limits: Very large data URLs may fail in some browsers. Prefer Blob URLs for generated content over a few megabytes.
- Mobile behavior varies: Some mobile browsers open files in a viewer app rather than saving to the filesystem, even with the
downloadattribute.
See Also
target— where links open (download overrides navigation)rel— link relationship typescrossorigin— CORS mode for cross-origin resources