@voidx-ai/react
v0.1.0
Published
React/Next.js wrapper for VoidX AI Addon (CDN standalone loader)
Downloads
141
Readme
@voidx/react
React/Next.js wrapper for VoidX AI Addon. Install one package, drop one component, and get a 3D AI agent with chat and voice on your site.
Install
npm install @voidx/reactRequires React 18 or later.
Quick Start
// app/layout.tsx (Next.js App Router)
import { VoidxAddon } from '@voidx/react';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html>
<body>
<VoidxAddon apiKey={process.env.NEXT_PUBLIC_VOIDX_API_KEY!} />
{children}
</body>
</html>
);
}This alone gives you a 3D AI agent with chat and voice.
Props
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| apiKey | string | Yes | JWT API key from VoidX dashboard |
| locale | 'ko' \| 'en' \| 'ja' \| 'zh' | No | Language (default: 'ko') |
| features | VoidxFeatures | No | Enable/disable features |
| theme | VoidxTheme | No | Color, font, border-radius customization |
| position | 'follow-cursor' \| 'bottom-right' \| 'bottom-left' | No | Agent position |
| actions | Record<string, (params) => Promise<any>> | No | Custom actions the AI can invoke |
| systemEvents | Record<string, SystemEventHandler> | No | Window event listeners that trigger AI responses |
| onReady | () => void | No | Called when SDK is fully loaded |
| onError | (error: Error) => void | No | Called on SDK errors |
| disabled | boolean | No | Set true to skip SDK loading |
| children | React.ReactNode | No | Children can use useVoidx() hook |
Features
Control which features are enabled:
<VoidxAddon
apiKey="..."
features={{
chat: true, // Chat popup (default: true)
cursor: true, // 3D cursor agent (default: true)
voice: true, // Voice agent (default: true)
hoverDetection: true, // Hover detection (default: true)
agentMode: '3d', // '3d' or 'parallax' (default: '3d')
}}
/>Actions
Actions are functions you define that the AI can call during a conversation. The AI decides when to call them based on what the user asks.
<VoidxAddon
apiKey="..."
actions={{
// AI calls this when user asks to search
search_products: async (params) => {
const res = await fetch(`/api/products?q=${params.query}`);
return res.json();
},
// AI calls this when user wants to add to cart
add_to_cart: async (params) => {
cartStore.addItem(params.productId);
return { success: true, message: 'Added to cart' };
},
// AI calls this when user wants to navigate
navigate_to: async (params) => {
router.push(params.path);
return { success: true };
},
}}
/>How it works:
- You register action functions with names like
search_products,add_to_cart - The AI learns that these actions are available
- During conversation, the AI decides which action to call based on user intent
- Your function runs, and the result is sent back to the AI
- The AI uses the result to generate a natural response
You can put any JavaScript logic inside an action: API calls, state management, DOM manipulation, page navigation, etc.
System Events
Listen for custom window events (e.g., order completed) and trigger an AI response automatically:
<VoidxAddon
apiKey="..."
systemEvents={{
'order-completed': {
handler: (detail, instance, locale) => ({
context: `Order ${detail.orderNumber} completed. Total: $${detail.total}`,
instruction: 'Thank the customer and mention shipping info.',
openChat: true, // Auto-open chat popup
}),
},
}}
/>Then dispatch the event from anywhere in your app:
// e.g., after checkout
window.dispatchEvent(
new CustomEvent('order-completed', {
detail: { orderNumber: 'ORD-123', total: 39.99 },
}),
);The AI will automatically respond with a contextual message like "Thank you for your order!"
useVoidx() Hook
Access the SDK instance from any child component:
import { VoidxAddon, useVoidx } from '@voidx/react';
// Parent: wrap children with VoidxAddon
function Layout({ children }) {
return (
<VoidxAddon apiKey="...">
{children}
</VoidxAddon>
);
}
// Child: use the hook
function AskAIButton() {
const voidx = useVoidx(); // null until SDK is ready
return (
<button onClick={() => voidx?.sendMessage('Recommend something')}>
Ask AI
</button>
);
}Available methods on voidx:
| Method | Description |
|--------|-------------|
| show() | Open chat popup |
| hide() | Close chat popup |
| sendMessage(text) | Send a message as the user |
| announceSystemEvent(context, options?) | Trigger an AI response without user message |
| setLocale(locale) | Change language |
| setTheme(theme) | Update theme |
| on(event, handler) | Listen to SDK events |
| off(event, handler) | Remove event listener |
| destroy() | Remove SDK from page |
Theme
<VoidxAddon
apiKey="..."
theme={{
primaryColor: '#6366f1',
gradientFrom: '#8b5cf6',
gradientTo: '#6366f1',
fontFamily: 'Pretendard, sans-serif',
borderRadius: 16,
}}
/>SDK Events
Listen to SDK lifecycle events via useVoidx():
const voidx = useVoidx();
useEffect(() => {
if (!voidx) return;
const onMessage = (msg) => console.log('New message:', msg);
voidx.on('voidx:message', onMessage);
return () => voidx.off('voidx:message', onMessage);
}, [voidx]);Available events: voidx:ready, voidx:error, voidx:message, voidx:chat:open, voidx:chat:close, voidx:voice:start, voidx:voice:end, voidx:voice:error, voidx:auth:expired, voidx:action:executed, voidx:action:error, voidx:destroy
Full Example
// app/layout.tsx
import { VoidxAddon } from '@voidx/react';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html>
<body>
<VoidxAddon
apiKey={process.env.NEXT_PUBLIC_VOIDX_API_KEY!}
locale="ko"
features={{ chat: true, cursor: true, voice: true, agentMode: '3d' }}
theme={{ primaryColor: '#6366f1', borderRadius: 16 }}
actions={{
search: async ({ query }) => {
const res = await fetch(`/api/search?q=${query}`);
return res.json();
},
navigate: async ({ path }) => {
window.location.href = path;
return { success: true };
},
}}
systemEvents={{
'checkout-done': {
handler: (detail, _instance, locale) => ({
context: locale === 'en'
? `Order ${detail.id} placed, total $${detail.total}`
: `주문 ${detail.id} 완료, 합계 $${detail.total}`,
instruction: locale === 'en'
? 'Thank the user warmly.'
: '따뜻하게 감사 인사를 전해주세요.',
openChat: true,
}),
},
}}
onReady={() => console.log('VoidX ready')}
>
{children}
</VoidxAddon>
</body>
</html>
);
}License
MIT
