@asktext/react
v1.0.5
Published
React components for AskText voice Q&A
Readme
@asktext/react
React components for AskText voice Q&A integration.
What it provides
- AskTextModal: Full-featured voice conversation modal with transcript, minimize/restore, quota tracking
- RichTextEditor: TipTap-based rich text editor with toolbar, syntax highlighting, image uploads
- AskTextButton: Simple button component that opens the voice modal
Installation
npm install @asktext/react @vapi-ai/webComponents
AskTextModal
The main voice conversation interface with real-time transcript and call controls.
import { AskTextModal } from '@asktext/react';
function MyComponent() {
const [isOpen, setIsOpen] = useState(false);
return (
<>
<button onClick={() => setIsOpen(true)}>Ask Article</button>
{isOpen && (
<AskTextModal
articleId="post-123"
onClose={() => setIsOpen(false)}
publicKey={process.env.NEXT_PUBLIC_VAPI_PUBLIC_KEY}
assistantId={process.env.NEXT_PUBLIC_VAPI_ASSISTANT_ID}
/>
)}
</>
);
}Props:
articleId(required): Unique identifier for the articleonClose(required): Callback when modal closespublicKey: Vapi public key (defaults to env var)assistantId: Vapi assistant ID (defaults to env var)quotaStartPath: API endpoint for quota check (default:/api/voice/start)quotaEndPath: API endpoint for usage tracking (default:/api/voice/end)bypassIps: Array of IP addresses to bypass quota limits
Features:
- Real-time conversation transcript
- Minimize/restore functionality
- Automatic scroll to latest messages
- ESC key support (minimize or close)
- Client-side and server-side quota tracking
- Graceful error handling
AskTextButton
Convenience component that combines button + modal in one.
import { AskTextButton } from '@asktext/react';
function ArticlePage({ article }) {
return (
<div>
<h1>{article.title}</h1>
<div>{article.content}</div>
{/* Inline button */}
<AskTextButton articleId={article.id} />
{/* Floating orb */}
<AskTextButton articleId={article.id} floating />
</div>
);
}Props:
articleId(required): Article identifierfloating: Render as floating orb instead of inline button- All other props from
AskTextModal
RichTextEditor
TipTap-based rich text editor with full formatting toolbar.
import { RichTextEditor } from '@asktext/react';
function PostEditor() {
const [content, setContent] = useState('');
return (
<RichTextEditor
initialContent={content}
onChange={setContent}
placeholder="Start writing..."
/>
);
}Props:
initialContent: HTML content to initialize editoronChange: Callback with HTML content on changesonBlur: Callback when editor loses focusplaceholder: Placeholder text
Features:
- Rich formatting (bold, italic, headings, quotes)
- Syntax-highlighted code blocks
- Link insertion and editing
- Image uploads (requires
/api/admin/images/uploadendpoint) - Collapsible sections
- Text highlighting
- Keyboard shortcuts
Environment Variables
# Required for voice features
NEXT_PUBLIC_VAPI_PUBLIC_KEY=pk_...
NEXT_PUBLIC_VAPI_ASSISTANT_ID=asst_...Styling
Components use Tailwind CSS classes. Ensure your project includes:
/* globals.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
/* Required for modal animations */
@keyframes slide-up {
from { transform: translateY(100%); opacity: 0; }
to { transform: translateY(0); opacity: 1; }
}
.animate-slide-up {
animation: slide-up 0.3s ease-out;
}
/* Color variables (customize as needed) */
:root {
--color-primary: #3b82f6;
--color-primary-light: #60a5fa;
}
.bg-primary { background-color: var(--color-primary); }
.bg-primary-light { background-color: var(--color-primary-light); }
.border-primary { border-color: var(--color-primary); }
.bg-primary\/20 { background-color: rgb(59 130 246 / 0.2); }Advanced Usage
Custom Quota Handling
<AskTextModal
articleId="post-123"
onClose={() => setIsOpen(false)}
quotaStartPath="/api/custom/voice/start"
quotaEndPath="/api/custom/voice/end"
bypassIps={['192.168.1.100']} // Dev IPs
/>Error Handling
function VoiceChat({ articleId }) {
const [error, setError] = useState(null);
return (
<>
{error && <div className="error">{error}</div>}
<AskTextModal
articleId={articleId}
onClose={() => setIsOpen(false)}
onError={setError} // Custom error handler
/>
</>
);
}Rich Text Editor with Custom Upload
// Ensure you have an image upload endpoint
// app/api/admin/images/upload/route.ts
export async function POST(request: Request) {
const formData = await request.formData();
const file = formData.get('image') as File;
// Upload logic here
const url = await uploadToStorage(file);
return Response.json({ url });
}TypeScript Support
All components include full TypeScript definitions:
import type {
AskTextModalProps,
RichTextEditorProps,
AskTextButtonProps
} from '@asktext/react';Browser Support
- Modern browsers: Chrome 90+, Firefox 88+, Safari 14+, Edge 90+
- Voice features: Requires microphone permissions
- WebRTC: Required for voice calls (most modern browsers)
License
MIT
