React Components
Upload and index files
The FileUpload component provides a drag-and-drop interface for uploading files to your EasyRAG dataset. It handles file selection, validation, progress tracking, and metadata attachment.
bashnpm install @easyrag/react-components
tsximport { FileUpload } from '@easyrag/react-components'; function App() { return ( <FileUpload token={yourToken} datasetId="my-dataset" onUploadComplete={(result) => { console.log('Uploaded files:', result.files); }} /> ); }
| Prop | Type | Description |
|---|---|---|
token | string | Authentication token (API key or frontend token) |
datasetId | string | Dataset ID where files will be uploaded |
| Prop | Type | Default | Description |
|---|---|---|---|
apiUrl | string | https://api.easyrag.com/v1 | API base URL |
maxFiles | number | 10 | Maximum number of files per upload |
maxFileSize | number | undefined | Maximum file size in bytes |
accept | object | undefined | Accepted file types (react-dropzone format) |
metadataBuilder | function | undefined | Function to build metadata per file |
chunkSize | number | undefined | Tokens per chunk (override default) |
chunkOverlap | number | undefined | Overlap between chunks |
| Prop | Type | Description |
|---|---|---|
onUploadStart | (files: File[]) => void | Called when upload begins |
onUploadComplete | (result: any) => void | Called when upload succeeds |
onUploadError | (error: Error) => void | Called when upload fails |
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | '' | Additional CSS classes |
theme | 'default' | 'minimal' | 'custom' | 'default' | Visual theme |
customStyles | object | {} | Custom CSS classes per element |
labels | object | {} | Custom text labels |
| Prop | Type | Default | Description |
|---|---|---|---|
showPoweredBy | boolean | true | Show "Powered by EasyRAG" |
poweredByUrl | string | 'https://easyrag.com' | URL for powered-by link |
tsx<FileUpload token={token} datasetId="my-dataset" onUploadComplete={(result) => { console.log(`Uploaded ${result.files.length} files`); }} />
tsx<FileUpload token={token} datasetId="documents" accept={{ 'application/pdf': ['.pdf'], 'application/msword': ['.doc', '.docx'] }} maxFileSize={10 * 1024 * 1024} // 10MB />
tsx<FileUpload token={token} datasetId="user-uploads" metadataBuilder={(file, index) => ({ userId: currentUser.id, department: currentUser.department, originalFileName: file.name, uploadedAt: new Date().toISOString(), uploadIndex: index })} />
tsx<FileUpload token={token} datasetId="technical-docs" chunkSize={800} chunkOverlap={100} onUploadComplete={(result) => { console.log('Files indexed with custom chunking'); }} />
tsx<FileUpload token={token} datasetId="shared-dataset" metadataBuilder={(file) => ({ customerId: currentCustomer.id, userId: currentUser.id, confidential: file.name.includes('confidential') })} />
tsx<FileUpload token={token} datasetId="my-dataset" theme="custom" customStyles={{ container: 'my-upload-container', dropzone: 'border-2 border-dashed border-blue-500 p-8', button: 'bg-blue-600 text-white px-6 py-2', error: 'text-red-600 font-semibold' }} />
tsx<FileUpload token={token} datasetId="my-dataset" labels={{ dropzone: 'Drop your documents here', dropzoneActive: 'Release to upload', uploading: 'Processing your files...', selectFiles: 'Choose Files' }} />
tsx<FileUpload token={token} datasetId="my-dataset" theme="minimal" showPoweredBy={false} />
The metadataBuilder function is called for each file and returns metadata that will be attached to all chunks from that file.
tsxmetadataBuilder={(file: File, index: number) => { return { // Custom fields - use any keys you want userId: 'user_123', department: 'engineering', uploadDate: new Date().toISOString(), // File info originalName: file.name, fileSize: file.size, fileType: file.type, // Index in upload batch uploadIndex: index }; }}
Later, you can filter searches by these metadata fields:
tsx<SearchBox token={token} datasetId="my-dataset" filters={[ { key: 'department', match: { value: 'engineering' } }, { key: 'userId', match: { value: 'user_123' } } ]} />
Use the accept prop to restrict file types (uses react-dropzone format):
tsx// Only PDFs accept={{ 'application/pdf': ['.pdf'] }} // PDFs and Word docs accept={{ 'application/pdf': ['.pdf'], 'application/msword': ['.doc'], 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': ['.docx'] }} // Images only accept={{ 'image/jpeg': ['.jpg', '.jpeg'], 'image/png': ['.png'] }} // Any file (default) accept={undefined}
EasyRAG automatically processes these file types:
.pdf).doc, .docx).xls, .xlsx).ppt, .pptx).txt).md).csv)tsx<FileUpload token={token} datasetId="my-dataset" onUploadError={(error) => { console.error('Upload failed:', error.message); // Show user-friendly message if (error.message.includes('INSUFFICIENT_CREDITS')) { alert('Out of credits. Please upgrade your plan.'); } else if (error.message.includes('FILE_TOO_LARGE')) { alert('File is too large. Maximum size is 10MB.'); } else { alert('Upload failed. Please try again.'); } }} />
tsx<FileUpload token={token} datasetId="my-dataset" onUploadStart={(files) => { console.log(`Starting upload of ${files.length} files`); setIsUploading(true); }} onUploadComplete={(result) => { console.log('Upload complete!'); setIsUploading(false); refreshFileList(); }} onUploadError={(error) => { console.error('Upload failed'); setIsUploading(false); }} />
Full TypeScript support:
typescriptimport type { FileUploadProps } from '@easyrag/react-components'; const uploadProps: FileUploadProps = { token: myToken, datasetId: 'my-dataset', maxFiles: 5, metadataBuilder: (file, index) => ({ userId: 'user_123', uploadIndex: index }) }; <FileUpload {...uploadProps} />
Available customStyles keys:
typescript{ container?: string; // Outer wrapper dropzone?: string; // Drop zone area dropzoneActive?: string; // Drop zone when dragging fileList?: string; // File list container button?: string; // Buttons error?: string; // Error messages }
tsx// ✅ Good - token from backend const token = await fetch('/api/tokens/create').then(r => r.json()); <FileUpload token={token.token} datasetId="dataset" /> // ❌ Bad - API key in frontend <FileUpload token={process.env.REACT_APP_API_KEY} datasetId="dataset" />
tsx// ✅ Good - searchable metadata metadataBuilder: (file) => ({ userId: currentUser.id, department: currentUser.department, documentType: getDocumentType(file.name), uploadDate: new Date().toISOString() }) // ❌ Bad - no metadata (harder to filter later) metadataBuilder: undefined
tsx// ✅ Good - reasonable limits <FileUpload maxFiles={10} maxFileSize={10 * 1024 * 1024} /> // ❌ Bad - no limits (potential abuse) <FileUpload />
tsx// ✅ Good - user-friendly error handling <FileUpload onUploadError={(error) => { showNotification({ type: 'error', message: getUserFriendlyMessage(error) }); }} />
Q: Can I upload multiple files at once?
A: Yes, use the maxFiles prop to control how many files can be uploaded in a single batch.
Q: How do I show upload progress?
A: Use the onUploadStart and onUploadComplete callbacks to track upload state.
Q: Can I customize the styling completely?
A: Yes, use theme="custom" and provide customStyles with your own CSS classes.
Q: What happens if upload fails?
A: The onUploadError callback is called with the error. The component displays an error message.
Q: Can I use this with Next.js?
A: Yes, the component works with Next.js. Make sure to use it in a client component ("use client").
Q: How do I hide the "Powered by" link?
A: Set showPoweredBy={false}.