Blog
frontend
2 min read

File Download using JavaScript: Various Techniques and Best Practices

Learn various techniques for implementing file downloads in the browser using JavaScript.

Implementing file downloads in the browser using JavaScript can be achieved through different methods depending on the source of the data and the desired user experience.

  • Key techniques include using Blob URLs, anchor tags with the download attribute, and handling binary data from APIs.

Background/Problem

While the server usually handles file delivery, the client often needs to trigger downloads for:

  • Dynamically generated content (e.g., CSV, JSON) created in the browser.
  • Files fetched via AJAX/Fetch that need to be saved locally.

Core Concepts

1) The Anchor Tag (<a>) Download Attribute

Modern browsers support the download attribute on <a> tags, which tells the browser to download the linked resource instead of navigating to it.

javascript
const link = document.createElement('a');\nlink.href = 'path/to/file';\nlink.download = 'filename.ext';\ndocument.body.appendChild(link);\nlink.click();\ndocument.body.removeChild(link);

→ Expected Result / What Changed:

The browser automatically starts downloading the file with the name provided in the attribute.


2) Using Blob and Object URLs

For data generated on the fly, you can create a Blob (Binary Large Object) and represent it as a temporary URL.

javascript
const content = \"Hello, World!\";\nconst blob = new Blob([content], { type: 'text/plain' });\nconst url = URL.createObjectURL(blob);\n\nconst a = document.createElement('a');\na.href = url;\na.download = 'hello.txt';\na.click();\n\nURL.revokeObjectURL(url); // Clean up memory

Remember to use URL.revokeObjectURL(url) to avoid memory leaks after the download is initiated.


Solution Approach

  1. Direct Link: Use a simple <a> tag for static files.
  2. Client-side Generation: Use Blob and URL.createObjectURL.
  3. API Data: Fetch as blob() then use the anchor tag hack.

Implementation (Code)

Example of downloading a file after fetching it from an API:

javascript
fetch('/api/download')\n  .then(res => res.blob())\n  .then(blob => {\n    const url = URL.createObjectURL(blob);\n    const a = document.createElement('a');\n    a.href = url;\n    a.download = 'file.pdf';\n    a.click();\n    URL.revokeObjectURL(url);\n  });

→ Expected Result / What Changed:

This allows you to customize the filename or perform authentication before starting the download.


Reproducing in Next.js (Execution via Button on Client)

javascript
\"use client\"\n\nexport default function DownloadDemo() {\n  const downloadText = () => {\n    const blob = new Blob([\"Hello from Next.js!\"], { type: 'text/plain' });\n    const url = URL.createObjectURL(blob);\n    const a = document.createElement('a');\n    a.href = url;\n    a.download = 'demo.txt';\n    a.click();\n    URL.revokeObjectURL(url);\n  };\n\n  return (\n    <div>\n      <button onClick={downloadText}>Download generated.txt</button>\n    </div>\n  );\n}

This demonstrates how to initiate a download purely from client-side logic in a Next.js environment.

Related Posts