Integrations
React/Next.js Integration
Integrate KoreShield SDK with React and Next.js applications
React/Next.js Integration
Learn how to integrate KoreShield's JavaScript SDK with React and Next.js applications for secure AI interactions.
Installation
npm install koreshield
# or
yarn add koreshield
# or
pnpm add koreshieldBasic Setup
Environment Variables
Create a .env.local file in your Next.js project:
KORESHIELD_BASE_URL=https://your-koreshield-instance.com
KORESHIELD_API_KEY=your-api-key-hereClient Configuration
Create a lib/koreshield.ts file:
import { createClient } from 'koreshield';
export const koreShield = createClient({
baseURL: process.env.KORESHIELD_BASE_URL!,
apiKey: process.env.KORESHIELD_API_KEY,
debug: process.env.NODE_ENV === 'development'
});React Hooks
useChat Hook
Create a custom hook for chat functionality:
import { useState, useCallback } from 'react';
import { koreShield } from '@/lib/koreshield';
import type { ChatCompletionRequest, ChatCompletionResponse } from 'koreshield';
export function useChat() {
const [messages, setMessages] = useState<Array<{ role: string; content: string }>>([]);
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const sendMessage = useCallback(async (content: string) => {
setIsLoading(true);
setError(null);
try {
const newMessages = [...messages, { role: 'user', content }];
setMessages(newMessages);
const response = await koreShield.createChatCompletion({
model: 'gpt-3.5-turbo',
messages: newMessages
});
const assistantMessage = response.choices[0]?.message;
if (assistantMessage) {
setMessages([...newMessages, assistantMessage]);
}
} catch (err) {
setError(err instanceof Error ? err.message : 'An error occurred');
} finally {
setIsLoading(false);
}
}, [messages]);
return {
messages,
isLoading,
error,
sendMessage,
clearMessages: () => setMessages([])
};
}Usage in Component
import { useChat } from '@/hooks/useChat';
export default function ChatComponent() {
const { messages, isLoading, error, sendMessage, clearMessages } = useChat();
const [input, setInput] = useState('');
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (input.trim()) {
await sendMessage(input.trim());
setInput('');
}
};
return (
<div className="chat-container">
<div className="messages">
{messages.map((msg, index) => (
<div key={index} className={`message ${msg.role}`}>
<strong>{msg.role}:</strong> {msg.content}
</div>
))}
</div>
{error && (
<div className="error">
Error: {error}
</div>
)}
<form onSubmit={handleSubmit}>
<input
type="text"
value={input}
onChange={(e) => setInput(e.target.value)}
placeholder="Type your message..."
disabled={isLoading}
/>
<button type="submit" disabled={isLoading || !input.trim()}>
{isLoading ? 'Sending...' : 'Send'}
</button>
<button type="button" onClick={clearMessages}>
Clear
</button>
</form>
</div>
);
}Next.js API Routes
Protected API Route
Create secure API routes with KoreShield protection:
// pages/api/chat.ts or app/api/chat/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { koreShield } from '@/lib/koreshield';
export async function POST(request: NextRequest) {
try {
const { messages, model = 'gpt-3.5-turbo' } = await request.json();
const response = await koreShield.createChatCompletion({
model,
messages
});
return NextResponse.json(response);
} catch (error) {
console.error('Chat API error:', error);
if (error.code === 'SECURITY_VIOLATION') {
return NextResponse.json(
{ error: 'Security violation detected', details: error.details },
{ status: 400 }
);
}
return NextResponse.json(
{ error: 'Internal server error' },
{ status: 500 }
);
}
}Client-Side API Call
import { useState } from 'react';
export default function ChatPage() {
const [messages, setMessages] = useState([]);
const [input, setInput] = useState('');
const [loading, setLoading] = useState(false);
const sendMessage = async () => {
setLoading(true);
try {
const response = await fetch('/api/chat', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
messages: [...messages, { role: 'user', content: input }]
})
});
const data = await response.json();
if (response.ok) {
setMessages(data.choices[0].message.content);
} else {
console.error('API Error:', data.error);
}
} catch (error) {
console.error('Network error:', error);
} finally {
setLoading(false);
}
};
return (
<div>
{/* Your chat UI */}
</div>
);
}Server-Side Rendering (SSR)
Data Fetching with KoreShield
// pages/chat.tsx
import { GetServerSideProps } from 'next';
import { koreShield } from '@/lib/koreshield';
interface ChatPageProps {
initialResponse?: string;
error?: string;
}
export const getServerSideProps: GetServerSideProps<ChatPageProps> = async () => {
try {
const response = await koreShield.createChatCompletion({
model: 'gpt-3.5-turbo',
messages: [{ role: 'user', content: 'Hello! Introduce yourself briefly.' }]
});
return {
props: {
initialResponse: response.choices[0]?.message?.content || 'No response'
}
};
} catch (error) {
return {
props: {
error: error.message
}
};
}
};
export default function ChatPage({ initialResponse, error }: ChatPageProps) {
return (
<div>
<h1>AI Chat</h1>
{error ? (
<p>Error: {error}</p>
) : (
<p>AI: {initialResponse}</p>
)}
</div>
);
}Error Handling
Global Error Boundary
// components/ErrorBoundary.tsx
import React from 'react';
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false, error: null };
}
static getDerivedStateFromError(error) {
return { hasError: true, error };
}
componentDidCatch(error, errorInfo) {
// Log to KoreShield monitoring
console.error('React Error Boundary:', error, errorInfo);
}
render() {
if (this.state.hasError) {
return (
<div className="error-boundary">
<h2>Something went wrong</h2>
<p>Please try refreshing the page</p>
<button onClick={() => window.location.reload()}>
Refresh Page
</button>
</div>
);
}
return this.props.children;
}
}
export default ErrorBoundary;Security Event Handling
import { useEffect } from 'react';
import { koreShield } from '@/lib/koreshield';
export function useSecurityMonitoring() {
useEffect(() => {
const checkSecurityEvents = async () => {
try {
const events = await koreShield.getSecurityEvents({
limit: 5,
severity: 'high'
});
if (events.length > 0) {
// Handle security events
console.warn('Security events detected:', events);
// Show user notification, log to monitoring service, etc.
}
} catch (error) {
console.error('Failed to check security events:', error);
}
};
// Check every 30 seconds
const interval = setInterval(checkSecurityEvents, 30000);
return () => clearInterval(interval);
}, []);
}Performance Optimization
React.memo for Chat Components
import { memo } from 'react';
const Message = memo(({ message, role }) => (
<div className={`message ${role}`}>
<strong>{role}:</strong> {message}
</div>
));
Message.displayName = 'Message';Suspense for Loading States
import { Suspense } from 'react';
function ChatMessages({ messages }) {
return (
<Suspense fallback={<div>Loading messages...</div>}>
{messages.map((msg, index) => (
<Message key={index} message={msg.content} role={msg.role} />
))}
</Suspense>
);
}Deployment Considerations
Environment Variables
Ensure these environment variables are set in your deployment platform:
KORESHIELD_BASE_URL=https://your-koreshield-instance.com
KORESHIELD_API_KEY=your-production-api-keyBuild Configuration
Add to your next.config.js:
/** @type {import('next').NextConfig} */
const nextConfig = {
env: {
KORESHIELD_BASE_URL: process.env.KORESHIELD_BASE_URL,
},
// Ensure API routes can access environment variables
serverRuntimeConfig: {
koreShieldApiKey: process.env.KORESHIELD_API_KEY,
},
};
module.exports = nextConfig;Testing
Unit Tests
// __tests__/useChat.test.tsx
import { renderHook, act } from '@testing-library/react';
import { useChat } from '@/hooks/useChat';
jest.mock('@/lib/koreshield', () => ({
koreShield: {
createChatCompletion: jest.fn()
}
}));
describe('useChat', () => {
it('should send message and update state', async () => {
const mockResponse = {
choices: [{ message: { role: 'assistant', content: 'Hello!' } }]
};
const { result } = renderHook(() => useChat());
await act(async () => {
await result.current.sendMessage('Hi');
});
expect(result.current.messages).toHaveLength(2);
expect(result.current.messages[1].content).toBe('Hello!');
});
});Troubleshooting
Common Issues
CORS Errors
- Ensure your KoreShield instance allows requests from your domain
- Check CORS configuration in your deployment
API Key Exposure
- Never commit API keys to version control
- Use environment variables for all secrets
- Rotate keys regularly
Rate Limiting
- Implement client-side rate limiting
- Handle 429 responses gracefully
- Consider caching responses
Memory Leaks
- Clean up event listeners in useEffect
- Avoid storing large objects in component state
- Use React DevTools to monitor memory usage