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

UsageBehavior
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 download has no value, the browser derives the filename from the URL path (e.g. /files/report.pdf saves as report.pdf).
  • If a value is provided, it overrides the URL-derived name but the server's Content-Disposition header 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 download value 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-Disposition headers 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-Disposition header, its filename takes priority over the download attribute 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 download attribute.

See Also

  • target — where links open (download overrides navigation)
  • rel — link relationship types
  • crossorigin — CORS mode for cross-origin resources