# EdgeStore Docs: Multi-file URL: https://edgestore.dev/docs/components/multi-file Source: https://raw.githubusercontent.com/edgestorejs/edgestore/refs/heads/main/docs/content/docs/components/multi-file.mdx import { DemoBlock } from '@/components/demo-block'; import { LimitedCode } from '@/components/ui/limited-code'; import { OpenTabs, OpenTabsContent, OpenTabsList, OpenTabsTrigger, } from '@/components/ui/open-tabs'; import MultiFileUploaderBlock from '@/components/upload/blocks/multi-file-block'; import { Step, Steps } from 'fumadocs-ui/components/steps'; Each file shows its type, size and progress. Failed uploads show the error with a retry button, and running uploads can be canceled. ## Installation CLI Manual Use the shadcn CLI to add the component to your project. npm pnpm yarn bun ```bash npx shadcn@latest add https://edgestore.dev/r/file-uploader.json ``` ```bash pnpm dlx shadcn@latest add https://edgestore.dev/r/file-uploader.json ``` ```bash yarn dlx shadcn@latest add https://edgestore.dev/r/file-uploader.json ``` ```bash bun x shadcn@latest add https://edgestore.dev/r/file-uploader.json ``` ### Setup for manual installation First you will need to follow the [manual install setup](./manual-install) guide. ### Install required components * [uploader-provider](./uploader-provider) * [dropzone](./dropzone) * [progress-bar](./progress-bar) * [shadcn/ui button](https://ui.shadcn.com/docs/components/button) ### Copy this component ````tsx title="components/upload/multi-file.tsx" 'use client'; import { Button } from '@/components/ui/button'; import { cn } from '@/lib/utils'; import { CheckIcon, RotateCwIcon, XIcon } from 'lucide-react'; import * as React from 'react'; import { type Accept } from 'react-dropzone'; import { Dropzone } from './dropzone'; import { ProgressBar } from './progress-bar'; import { fileExtension, fileKind, formatFileSize, type FileKind, } from './upload-utils'; import { useUploader, type FileState } from './uploader-provider'; const KIND_CLASSNAMES: Record = { image: 'text-purple-600 dark:text-purple-400', video: 'text-pink-600 dark:text-pink-400', audio: 'text-cyan-600 dark:text-cyan-400', pdf: 'text-red-600 dark:text-red-400', doc: 'text-blue-600 dark:text-blue-400', sheet: 'text-green-600 dark:text-green-400', slides: 'text-orange-600 dark:text-orange-400', archive: 'text-yellow-600 dark:text-yellow-400', code: 'text-teal-600 dark:text-teal-400', other: 'text-muted-foreground', }; /** * A colored tile with the file's extension. */ export function FileBadge({ file, className, }: { file: File; className?: string; }) { return ( ); } function IconButton({ label, className, ...props }: React.ComponentProps<'button'> & { label: string }) { return ( )} ); } ```` ## Usage Install or copy the component from [Installation](#installation) before using this example. ```tsx 'use client'; import { FileUploader } from '@/components/upload/multi-file'; import { UploaderProvider, type UploadFn, } from '@/components/upload/uploader-provider'; import { useEdgeStore } from '@/lib/edgestore'; import * as React from 'react'; export function MultiFileDropzoneUsage() { const { edgestore } = useEdgeStore(); const uploadFn: UploadFn = React.useCallback( async ({ file, onProgressChange, signal }) => { const res = await edgestore.publicFiles.upload({ file, signal, onProgressChange, }); // you can run some server action or api here // to add the necessary data to your database console.log(res); return res; }, [edgestore], ); return ( ); } ``` ## Props | Prop | Type | Default | Description | | ------------------- | --------- | --------- | ------------------------------------------------------------------------------------------------------------------------ | | `maxFiles` | `number` | | Maximum number of files in total. | | `maxSize` | `number` | | Maximum file size in bytes. | | `accept` | `Accept` | all types | Accepted file types, in [react-dropzone's format](https://react-dropzone.js.org/#section-accepting-specific-file-types). | | `typesLabel` | `string` | | Human-readable list of accepted types, shown in the hint and in error messages. | | `disabled` | `boolean` | `false` | Disables the component. | | `dropzoneClassName` | `string` | | Additional className for the dropzone. | | `fileListClassName` | `string` | | Additional className for the file list. | ### Building your own layout `multi-file.tsx` also exports the pieces it is made of, so you can arrange them differently: * `FileList` lists the files of the nearest `UploaderProvider`. * `FileListItem` renders one file with its status and actions. * `FileBadge` renders the colored file-type tile.