utilcn
componentdownload-filesource: ok · hit
Download A File From Storage
Download a file from a storage provider using a presigned download URL.
npx shadcn add "https://utilcn.dev/r/download-file.json"free
No selection tags yet — empty means no evidence, not lack of support.
Dependencies
Bundle weight · lighticonslucide-react
Files2 · source cached 10/15/2026, 10:49:03 AM
registry/default/storage/download-file.tsx
'use client';
import { Download } from 'lucide-react';
import type { PropsWithChildren } from 'react';
import { cn } from '@/lib/utils';
import { useDownloadFile } from '@/registry/default/storage/use-download-file';
type DownloadFileProps = PropsWithChildren<{
fileKey: string;
fileName?: string;
className?: string;
}>;
export function DownloadFile({
fileKey,
fileName,
children,
className,
}: DownloadFileProps) {
const downloadFile = useDownloadFile();
const handleDownload = () => {
downloadFile.mutate(
{ fileKey, fileName },
{
onSuccess: (url: string) => {
console.log('Download initiated:', url);
},
onError: (err: Error) => {
console.error(`Download failed: ${(err as Error).message}`);
},
},
);
};
return (
<button
className={cn('flex items-center gap-2', className)}
disabled={downloadFile.isPending}
onClick={handleDownload}
type="button"
>
{children || (
<>
<Download className="mr-2 h-4 w-4" />
{downloadFile.isPending ? 'Downloading...' : 'Download'}
</>
)}
</button>
);
}
registry/default/storage/use-download-file.ts
import { useMutation } from '@tanstack/react-query';
type DownloadArgs = {
fileKey: string;
fileName?: string;
};
export function useDownloadFile() {
return useMutation({
mutationFn: async ({ fileKey, fileName }: DownloadArgs) => {
const downloadRes = await fetch('/api/downloads/presign', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ key: fileKey }),
});
if (!downloadRes.ok) throw new Error('Failed to get download URL');
const { downloadUrl } = await downloadRes.json();
const response = await fetch(downloadUrl);
const blob = await response.blob();
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = fileName || fileKey.split('/').pop() || 'download';
document.body.appendChild(link);
link.click();
link.remove();
window.URL.revokeObjectURL(url);
return downloadUrl;
},
});
}