React Components

File Viewer Component

View uploaded documents

FileViewer Component

The FileViewer component provides a file browser and management interface for your uploaded documents. Users can view files, see details, and manage their document library.

Installation

bash
npm install @easyrag/react-components

Basic Usage

tsx
import { FileViewer } from '@easyrag/react-components'; function App() { return ( <FileViewer token={yourToken} datasetId="my-dataset" /> ); }

Features

  • File Listing - Browse all uploaded files
  • Auto-Load - Automatically fetch files on mount
  • File Details - View metadata, transcriptions, and more
  • File Management - Open and delete files
  • 3 Layouts - Split, list, or grid view
  • Filtering - Filter by metadata
  • Theming - 3 built-in themes + custom styling

Props

Required Props

PropTypeDescription
tokenstringAuthentication token (frontend token recommended)
datasetIdstringDataset ID to browse

Optional Props

PropTypeDefaultDescription
apiUrlstringhttps://api.easyrag.com/v1API base URL
filtersarray[]Metadata filters to apply
filesarrayundefinedPre-loaded files (skips auto-load)
autoLoadbooleantrueAuto-load files on mount
layout'split' | 'list' | 'grid''split'Display layout
showSizebooleantrueShow file sizes
showExtensionbooleantrueShow file extensions
showMetadatabooleanfalseShow metadata panel
showTranscriptionbooleantrueShow transcriptions (audio/video)
showDeleteButtonbooleantrueShow delete file button
showOpenButtonbooleantrueShow open file button
theme'default' | 'minimal' | 'custom''default'Visual theme
classNamestring''Additional CSS classes
customStylesobject{}Custom CSS class overrides
labelsobject{}Custom text labels
showPoweredBybooleantrueShow "Powered by EasyRAG"
poweredByUrlstringhttps://easyrag.comPowered by link URL

Callback Props

PropTypeDescription
onFileSelect(file: FileMetadata) => voidCalled when file is selected
onFileDelete(fileId: string) => voidCalled when file is deleted
onFilesLoad(files: FileMetadata[]) => voidCalled when files are loaded
onError(error: Error) => voidCalled when an error occurs

Examples

Basic File Browser

tsx
<FileViewer token={token} datasetId="my-dataset" />

Split Layout (Default)

File list on left, details panel on right:

tsx
<FileViewer token={token} datasetId="my-dataset" layout="split" showMetadata={true} />

List Layout

Files only, no details panel:

tsx
<FileViewer token={token} datasetId="my-dataset" layout="list" showSize={true} showExtension={true} />

Grid Layout

Grid of file cards:

tsx
<FileViewer token={token} datasetId="my-dataset" layout="grid" />

Filtered Files

Show only specific files:

tsx
<FileViewer token={token} datasetId="shared-dataset" filters={[ { key: 'userId', match: { value: currentUser.id } }, { key: 'department', match: { value: 'engineering' } } ]} />

Read-Only Mode

No delete button:

tsx
<FileViewer token={token} datasetId="my-dataset" showDeleteButton={false} showOpenButton={true} />

With Callbacks

tsx
<FileViewer token={token} datasetId="my-dataset" onFileSelect={(file) => { console.log('Selected file:', file.originalName); }} onFileDelete={(fileId) => { console.log('Deleted file:', fileId); toast.success('File deleted'); }} onFilesLoad={(files) => { console.log(`Loaded ${files.length} files`); }} onError={(error) => { console.error('File viewer error:', error); toast.error('Failed to load files'); }} />

Pre-Loaded Files

Pass files manually (skips auto-load):

tsx
function MyFileViewer() { const [files, setFiles] = useState([]); useEffect(() => { // Load files yourself loadFiles().then(setFiles); }, []); return ( <FileViewer token={token} datasetId="my-dataset" files={files} autoLoad={false} /> ); }

Custom Styling

tsx
<FileViewer token={token} datasetId="my-dataset" theme="custom" customStyles={{ container: 'my-viewer-wrapper', fileList: 'my-file-list', fileItem: 'my-file-item', fileItemActive: 'my-active-item', detailsPanel: 'my-details-panel', }} />

Custom Labels

tsx
<FileViewer token={token} datasetId="my-dataset" labels={{ title: 'Your Documents', emptyState: 'No files uploaded yet', selectFile: 'Select a file to view details', openFile: 'View File', deleteFile: 'Remove', confirmDelete: 'Are you sure you want to delete this file?', }} />

Layouts

Split Layout

Best for: Detailed file inspection

tsx
<FileViewer layout="split" />

Shows:

  • File list (left)
  • Details panel (right)
  • File metadata
  • Transcriptions
  • Action buttons

List Layout

Best for: Quick browsing

tsx
<FileViewer layout="list" />

Shows:

  • Compact file list
  • No details panel
  • Click to select only

Grid Layout

Best for: Visual browsing

tsx
<FileViewer layout="grid" />

Shows:

  • Grid of file cards
  • File icons/thumbnails
  • Basic info

Themes

Default Theme

Modern, polished design with EasyRAG branding:

tsx
<FileViewer token={token} datasetId="dataset" theme="default" />

Minimal Theme

Clean, simple styling:

tsx
<FileViewer token={token} datasetId="dataset" theme="minimal" />

Custom Theme

Full control over styling:

tsx
<FileViewer token={token} datasetId="dataset" theme="custom" customStyles={{ container: 'bg-white rounded-lg shadow-lg p-6', fileList: 'border border-gray-300 divide-y', fileItem: 'p-3 hover:bg-gray-50 cursor-pointer', fileItemActive: 'bg-blue-50 border-l-4 border-blue-600', detailsPanel: 'border border-gray-300 rounded p-4', }} />

TypeScript

Full TypeScript support included:

typescript
import type { FileViewerProps, FileMetadata } from '@easyrag/react-components'; interface FileMetadata { fileId: string; originalName: string; extension?: string; size?: number; filePath?: string; created?: string; mimeType?: string; transcriptionText?: string; transcriptionSrt?: string; permanentUrl?: string; extraMeta?: Record<string, any>; } const props: FileViewerProps = { token: 'your-token', datasetId: 'my-dataset', layout: 'split', onFileSelect: (file: FileMetadata) => { console.log(file); } };

Styling

Target specific elements with CSS:

css
/* Container */ .easyrag-file-viewer { } /* File list */ .easyrag-file-viewer .file-list { } /* Individual file item */ .easyrag-file-viewer .file-item { } /* Active/selected file */ .easyrag-file-viewer .file-item-active { } /* Details panel */ .easyrag-file-viewer .details-panel { } /* Buttons */ .easyrag-file-viewer button { }

Integration with Other Components

With FileUpload

Refresh viewer after upload:

tsx
function DocumentManager() { const [refreshKey, setRefreshKey] = useState(0); return ( <> <FileUpload token={token} datasetId="dataset" onUploadComplete={() => { setRefreshKey(prev => prev + 1); }} /> <FileViewer key={refreshKey} token={token} datasetId="dataset" layout="split" /> </> ); }

With SearchBox

Highlight searched files:

tsx
function SearchableFileList() { const [searchResults, setSearchResults] = useState([]); const [selectedFile, setSelectedFile] = useState(null); return ( <> <SearchBox token={token} datasetId="dataset" onResults={(results) => { setSearchResults(results); // Get fileIds from results const fileIds = results.map(r => r.metadata.fileId); console.log('Results from files:', fileIds); }} /> <FileViewer token={token} datasetId="dataset" onFileSelect={(file) => setSelectedFile(file)} /> </> ); }

Complete File Management System

tsx
function FileManagementApp() { const [files, setFiles] = useState([]); const [filter, setFilter] = useState(''); return ( <div className="space-y-6"> {/* Upload */} <FileUpload token={token} datasetId="dataset" onUploadComplete={(result) => { setFiles(prev => [...prev, ...result.files]); }} /> {/* Filter */} <input type="text" placeholder="Filter by name..." value={filter} onChange={(e) => setFilter(e.target.value)} /> {/* View */} <FileViewer token={token} datasetId="dataset" files={files.filter(f => f.originalName.includes(filter) )} layout="split" showMetadata={true} onFileDelete={(fileId) => { setFiles(prev => prev.filter(f => f.fileId !== fileId)); }} /> </div> ); }

Use Cases

Document Library

tsx
<FileViewer token={token} datasetId="company-docs" layout="grid" filters={[ { key: 'department', match: { value: user.department } } ]} showMetadata={true} />

Media Manager

tsx
<FileViewer token={token} datasetId="media-files" layout="grid" showTranscription={true} filters={[ { key: 'type', match: { value: 'audio' } } ]} />

Personal File Browser

tsx
<FileViewer token={token} datasetId="my-files" layout="split" filters={[ { key: 'userId', match: { value: currentUser.id } } ]} showSize={true} showDeleteButton={true} />

Best Practices

1. Use Frontend Tokens

Generate short-lived tokens from your backend:

typescript
// Backend app.post('/api/tokens/create', authenticate, async (req, res) => { const token = signFrontendToken({ customerId: req.user.id, datasetId: req.body.datasetId, ttlSeconds: 3600 }); res.json({ token }); });

2. Filter for Security

Always filter to user's own files:

tsx
<FileViewer token={token} datasetId="shared-dataset" filters={[ { key: 'userId', match: { value: currentUser.id } } ]} />

3. Handle File Selection

tsx
<FileViewer token={token} datasetId="dataset" onFileSelect={(file) => { // Update URL router.push(`/files/${file.fileId}`); // Track analytics analytics.track('file_viewed', { fileId: file.fileId, fileName: file.originalName }); }} />

4. Confirm Deletions

The component shows a browser confirm dialog by default. Customize the message:

tsx
<FileViewer token={token} datasetId="dataset" labels={{ confirmDelete: 'Are you sure? This cannot be undone.' }} onFileDelete={(fileId) => { // Clean up related data deleteRelatedChunks(fileId); toast.success('File deleted successfully'); }} />

5. Choose the Right Layout

  • Split - When users need detailed file info
  • List - When users need to browse quickly
  • Grid - When visual recognition matters
tsx
// Let users choose const [layout, setLayout] = useState('split'); <select value={layout} onChange={(e) => setLayout(e.target.value)}> <option value="split">Split</option> <option value="list">List</option> <option value="grid">Grid</option> </select> <FileViewer layout={layout} {...props} />

Accessibility

The FileViewer component includes:

  • Semantic HTML
  • Keyboard navigation
  • ARIA labels
  • Focus management
  • Screen reader support

Browser Support

  • Chrome/Edge: Latest 2 versions
  • Firefox: Latest 2 versions
  • Safari: Latest 2 versions

Related Components

Support

Need help? Contact us at: