Skip to content

EasyRAG/react-components

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

2 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

@easyrag/react-components

Production-ready React components for EasyRAG - add RAG to your app in minutes.

Installation

npm install @easyrag/react-components

Components

  • FileUpload - Upload and index documents
  • SearchBox - Semantic search interface
  • ChatBox - AI chat with streaming responses
  • FileViewer - Browse and manage uploaded files

Quick Start

FileUpload

import { FileUpload } from '@easyrag/react-components';

function App() {
  return (
    <FileUpload
      token={yourToken}
      datasetId="my-dataset"
      onUploadComplete={(result) => {
        console.log('Upload complete!', result);
      }}
    />
  );
}

SearchBox

import { SearchBox } from '@easyrag/react-components';

function App() {
  return (
    <SearchBox
      token={yourToken}
      datasetId="my-dataset"
      onResults={(results) => {
        console.log('Search results:', results);
      }}
    />
  );
}

ChatBox

import { ChatBox } from '@easyrag/react-components';

function App() {
  return (
    <ChatBox
      token={yourToken}
      datasetId="my-dataset"
      stream={true}
    />
  );
}

FileViewer

import { FileViewer } from '@easyrag/react-components';

function App() {
  return (
    <FileViewer
      token={yourToken}
      datasetId="my-dataset"
      onFileSelect={(file) => {
        console.log('Selected file:', file);
      }}
    />
  );
}

Authentication

Components support two authentication modes:

Mode 1: Frontend Tokens (Recommended)

Generate short-lived tokens from your backend:

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

// Frontend usage
const token = await fetch('/api/tokens/create', {
  method: 'POST',
  body: JSON.stringify({ datasetId: 'my-dataset' })
}).then(r => r.json()).then(d => d.token);

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

Mode 2: API Keys (Internal Tools Only)

For internal tools or testing:

<FileUpload
  token={process.env.EASYRAG_API_KEY}
  datasetId="my-dataset"
/>

⚠️ Never expose API keys in production frontends!

Customization

Themes

Three built-in themes:

<SearchBox
  token={token}
  datasetId="my-dataset"
  theme="default"  // Default EasyRAG styling
  theme="minimal"  // Clean, minimal design
  theme="custom"   // Use customStyles
/>

Custom Styles

<SearchBox
  token={token}
  datasetId="my-dataset"
  theme="custom"
  customStyles={{
    container: 'my-search-container',
    input: 'my-custom-input',
    button: 'my-custom-button',
    resultCard: 'my-result-card',
  }}
/>

Custom Labels

<ChatBox
  token={token}
  datasetId="my-dataset"
  labels={{
    placeholder: 'Ask me anything...',
    buttonSend: 'Submit',
    emptyState: 'Start chatting!',
  }}
/>

Powered By Watermark

<FileUpload
  token={token}
  datasetId="my-dataset"
  showPoweredBy={true}  // Default: true
  poweredByUrl="https://easyrag.com"  // Default
/>

// Hide watermark (not recommended)
<FileUpload
  showPoweredBy={false}
/>

API Reference

FileUpload Props

Prop Type Default Description
token string required Auth token
datasetId string required Dataset ID
apiUrl string https://api.easyrag.com/v1 API base URL
metadataBuilder function undefined Build metadata per file
maxFiles number 10 Max files per upload
maxFileSize number undefined Max file size (bytes)
accept object undefined Accepted file types
chunkSize number undefined Tokens per chunk
chunkOverlap number undefined Overlap between chunks
onUploadStart function undefined Called when upload starts
onUploadComplete function undefined Called on success
onUploadError function undefined Called on error
theme 'default' | 'minimal' | 'custom' 'default' Visual theme
customStyles object {} Custom CSS classes
labels object {} Custom text labels
showPoweredBy boolean true Show "Powered by EasyRAG"

SearchBox Props

Prop Type Default Description
token string required Auth token
datasetId string required Dataset ID
apiUrl string https://api.easyrag.com/v1 API base URL
filters array [] Metadata filters
limit number 5 Results per search
maxResults number 10 Max results to display
showScore boolean true Show relevance scores
showMetadata boolean false Show metadata
onSearch function undefined Called on search
onResults function undefined Called with results
onError function undefined Called on error
renderResult function undefined Custom result renderer
theme 'default' | 'minimal' | 'custom' 'default' Visual theme
customStyles object {} Custom CSS classes
labels object {} Custom text labels
showPoweredBy boolean true Show "Powered by EasyRAG"

ChatBox Props

Prop Type Default Description
token string required Auth token
datasetId string required Dataset ID
apiUrl string https://api.easyrag.com/v1 API base URL
filters array [] Metadata filters
stream boolean true Enable streaming
maxHeight string '400px' Max chat height
initialMessages array [] Pre-populate messages
onMessage function undefined Called on new message
onError function undefined Called on error
onStreamStart function undefined Called when stream starts
onStreamEnd function undefined Called when stream ends
theme 'default' | 'minimal' | 'custom' 'default' Visual theme
customStyles object {} Custom CSS classes
labels object {} Custom text labels
showPoweredBy boolean true Show "Powered by EasyRAG"

Advanced Examples

Multi-Tenant Upload

<FileUpload
  token={token}
  datasetId="shared-dataset"
  metadataBuilder={(file, index) => ({
    userId: currentUser.id,
    department: currentUser.department,
    uploadedAt: new Date().toISOString(),
    originalFileName: file.name,
  })}
  onUploadComplete={(result) => {
    console.log(`Uploaded ${result.files.length} files`);
  }}
/>

Filtered Search

<SearchBox
  token={token}
  datasetId="company-docs"
  filters={[
    { key: 'department', match: { value: 'engineering' } },
    { key: 'confidential', match: { value: false } },
  ]}
  onResults={(results) => {
    console.log(`Found ${results.length} results`);
  }}
/>

Custom Result Rendering

<SearchBox
  token={token}
  datasetId="my-dataset"
  renderResult={(result, index) => (
    <div className="custom-result">
      <h3>{result.metadata.title}</h3>
      <p>{result.pageContent}</p>
      <span>Relevance: {(result.score * 100).toFixed(1)}%</span>
    </div>
  )}
/>

Chat with Context

<ChatBox
  token={token}
  datasetId="support-docs"
  filters={[
    { key: 'category', match: { value: 'billing' } }
  ]}
  initialMessages={[
    {
      id: 1,
      role: 'assistant',
      content: 'Hi! I can help with billing questions.',
    },
  ]}
  onMessage={(message) => {
    // Log messages to analytics
    analytics.track('chat_message', {
      role: message.role,
      length: message.content.length,
    });
  }}
/>

Complete Example

import { useState } from 'react';
import { FileUpload, SearchBox, ChatBox } from '@easyrag/react-components';

function RAGDemo() {
  const [token, setToken] = useState('');
  const [filesUploaded, setFilesUploaded] = useState(false);

  // Get token from your backend
  useEffect(() => {
    fetch('/api/tokens/create', {
      method: 'POST',
      body: JSON.stringify({ datasetId: 'my-dataset' })
    })
      .then(r => r.json())
      .then(data => setToken(data.token));
  }, []);

  if (!token) return <div>Loading...</div>;

  return (
    <div className="max-w-4xl mx-auto p-6 space-y-8">
      <h1>RAG Demo</h1>
      
      {/* Upload */}
      <FileUpload
        token={token}
        datasetId="my-dataset"
        onUploadComplete={() => setFilesUploaded(true)}
      />

      {/* Search */}
      {filesUploaded && (
        <SearchBox
          token={token}
          datasetId="my-dataset"
          showScore={true}
        />
      )}

      {/* Chat */}
      {filesUploaded && (
        <ChatBox
          token={token}
          datasetId="my-dataset"
          stream={true}
          maxHeight="500px"
        />
      )}
    </div>
  );
}

TypeScript

Full TypeScript support included:

import type {
  FileUploadProps,
  SearchBoxProps,
  SearchResult,
  ChatBoxProps,
  Message,
} from '@easyrag/react-components';

Styling

Components use semantic class names for easy styling:

/* Target specific components */
.easyrag-file-upload { }
.easyrag-search-box { }
.easyrag-chat-box { }

/* Target specific elements */
.easyrag-file-upload input { }
.easyrag-search-box button { }
.easyrag-chat-box .message-user { }

Browser Support

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

License

MIT

Support

Related Packages

FileViewer Props

Prop Type Default Description
token string required Auth token
datasetId string required Dataset ID
apiUrl string https://api.easyrag.com/v1 API base URL
filters array [] Metadata filters
files array undefined Pre-loaded files (optional)
autoLoad boolean true Auto-load files on mount
showSize boolean true Show file sizes
showExtension boolean true Show file extensions
showMetadata boolean false Show file metadata
showTranscription boolean true Show transcriptions
showDeleteButton boolean true Show delete button
showOpenButton boolean true Show open file button
layout 'split' | 'list' | 'grid' 'split' Layout mode
onFileSelect function undefined Called when file selected
onFileDelete function undefined Called when file deleted
onFilesLoad function undefined Called when files load
onError function undefined Called on error
theme 'default' | 'minimal' | 'custom' 'default' Visual theme
customStyles object {} Custom CSS classes
labels object {} Custom text labels
showPoweredBy boolean true Show "Powered by EasyRAG"

File Management with Viewer

import { FileUpload, FileViewer } from '@easyrag/react-components';

function FileManager() {
  const [refreshKey, setRefreshKey] = useState(0);

  return (
    <div className="space-y-6">
      {/* Upload new files */}
      <FileUpload
        token={token}
        datasetId="my-dataset"
        onUploadComplete={() => {
          setRefreshKey(prev => prev + 1); // Refresh viewer
        }}
      />

      {/* View and manage files */}
      <FileViewer
        key={refreshKey}
        token={token}
        datasetId="my-dataset"
        layout="split"
        showMetadata={true}
        showTranscription={true}
        onFileDelete={(fileId) => {
          console.log('File deleted:', fileId);
        }}
      />
    </div>
  );
}

Filtered File Viewer

<FileViewer
  token={token}
  datasetId="shared-dataset"
  filters={[
    { key: 'userId', match: { value: currentUser.id } },
    { key: 'department', match: { value: 'engineering' } }
  ]}
  onFileSelect={(file) => {
    console.log('Selected:', file.originalName);
  }}
/>

List Layout with Custom Styling

<FileViewer
  token={token}
  datasetId="my-dataset"
  layout="list"
  theme="custom"
  customStyles={{
    fileItem: 'p-4 border-b hover:bg-blue-50',
    fileItemActive: 'bg-blue-100 border-l-4 border-l-blue-500',
  }}
  showSize={true}
  showExtension={true}
  showDeleteButton={false}  // Read-only mode
/>

About

React components for EasyRAG - RAG as a Service

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published