useDownload

NEW

React hook to download a file.

import { useState } from 'react'

export const useDownload = () => {
  const [error, setError] = useState<Error | unknown | null>(null)
  const [isDownloading, setIsDownloading] = useState<boolean>(false)

  const handleResponse = async (response: Response): Promise<string> => {
    if (!response.ok) {
      throw new Error('Could not download file')
    }

    const blob = await response.blob()
    const url = window.URL.createObjectURL(new Blob([blob]))

    return url
  }

  const handleDownload = (fileName: string, url: string) => {
    const link = document.createElement('a')

    link.href = url
    link.setAttribute('download', fileName)
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    window.URL.revokeObjectURL(url)
  }

  const downloadFile = async (fileName: string, fileUrl: string) => {
    setIsDownloading(true)

    try {
      const response = await fetch(fileUrl)
      const url = await handleResponse(response)

      handleDownload(fileName, url)
    } catch (error) {
      setError(error)
    } finally {
      setIsDownloading(false)
    }
  }

  return {
    error,
    isDownloading,
    downloadFile,
  }
}

React 16.8 or higher

  • Name
    error
    Type
    Error | unknown | null
    Description

    Represents any error that occurs during the download process, or null if no error occurs.

  • Name
    isDownloading
    Type
    boolean
    Description

    Indicates whether a file is currently being downloaded (true) or not(false).

  • Name
    downloadFile
    Type
    function
    Description

    Initiate the file download process. Accept two parameters: fileName a string that represents the name to be given to the downloaded file and fileUrl a string that represents the URL from which the file is to be downloaded.

import { useDownload } from './hooks/useDownload'

const App = () => {
  const { error, isDownloading, downloadFile } = useDownload()

  const handleDownload = () => {
    const fileName = 'example.pdf'
    const fileUrl = 'https://example.com/example.pdf'
    downloadFile(fileName, fileUrl)
  }

  return (
    <div>
      <button onClick={handleDownload} disabled={isDownloading}>
        {isDownloading ? 'Downloading...' : 'Download File'}
      </button>
      {error && <div>Error: {error.message}</div>}
    </div>
  )
}

export default App

Here are some use cases where this React hook is useful:

  • Downloading PDF invoices in an e-commerce application
  • Exporting data as a CSV file in a data visualization dashboard
  • Providing downloadable resources (e.g., whitepapers, guides) on a website