Integrating DeepSeek R1 into Your React Application: A Comprehensive Technical Guide
DeepSeek R1 represents a significant leap in AI-powered search capabilities, offering semantic understanding, vector search, and hybrid ranking. This tutorial will walk you through integrating DeepSeek R1 into a React application with proper authentication, query handling, and response rendering.
Prerequisites
Before beginning, ensure you have:
- Node.js (v18+ recommended)
- React (v18+)
- DeepSeek R1 API credentials
- Basic understanding of async/await and React hooks
Step 1: Setting Up the React Project
Create a new React project if you don't have one already:
npx create-react-app deepseek-integration
cd deepseek-integration
Install required dependencies:
npm install axios @tanstack/react-query react-markdown
Step 2: Configure DeepSeek R1 API Client
Create a new file src/lib/deepseek.js:
import axios from 'axios';
const DEEPSEEK_API_URL = 'https://api.deepseek.com/v1/r1/search';
const DEEPSEEK_API_KEY = process.env.REACT_APP_DEEPSEEK_API_KEY;
const deepseekClient = axios.create({
baseURL: DEEPSEEK_API_URL,
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${DEEPSEEK_API_KEY}`
},
timeout: 10000
});
export const search = async (query, options = {}) => {
const params = {
query,
max_results: options.maxResults || 10,
semantic_weight: options.semanticWeight || 0.7,
hybrid: options.hybrid || true,
filters: options.filters || {}
};
try {
const response = await deepseekClient.post('/search', params);
return response.data;
} catch (error) {
console.error('DeepSeek R1 API Error:', error);
throw error;
}
};
Step 3: Create a Custom Hook for Search
Create src/hooks/useDeepSeek.js:
import { useMutation } from '@tanstack/react-query';
import { search } from '../lib/deepseek';
export const useDeepSeekSearch = () => {
return useMutation({
mutationFn: ({ query, options }) => search(query, options),
onError: (error) => {
console.error('Search failed:', error);
}
});
};
Step 4: Build the Search Component
Create src/components/DeepSeekSearch.jsx:
import { useState } from 'react';
import { useDeepSeekSearch } from '../hooks/useDeepSeek';
import ReactMarkdown from 'react-markdown';
export const DeepSeekSearch = () => {
const [query, setQuery] = useState('');
const [options, setOptions] = useState({
maxResults: 5,
semanticWeight: 0.7,
hybrid: true
});
const { mutate, data, isPending, error } = useDeepSeekSearch();
const handleSearch = (e) => {
e.preventDefault();
mutate({ query, options });
};
return (
<div className="deepseek-container">
<form onSubmit={handleSearch}>
<input
type="text"
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="Enter your search query..."
/>
<button type="submit" disabled={isPending}>
{isPending ? 'Searching...' : 'Search'}
</button>
</form>
<div className="options-panel">
<label>
Max Results:
<input
type="number"
min="1"
max="20"
value={options.maxResults}
onChange={(e) => setOptions({...options, maxResults: parseInt(e.target.value)})}
/>
</label>
<label>
Semantic Weight:
<input
type="range"
min="0"
max="1"
step="0.1"
value={options.semanticWeight}
onChange={(e) => setOptions({...options, semanticWeight: parseFloat(e.target.value)})}
/>
{options.semanticWeight}
</label>
</div>
{error && <div className="error">Error: {error.message}</div>}
<div className="results-container">
{data?.results?.map((result, index) => (
<div key={index} className="result-item">
<h3>{result.title}</h3>
<div className="result-meta">
<span>Score: {result.score.toFixed(3)}</span>
<span>Type: {result.type}</span>
</div>
<div className="result-content">
<ReactMarkdown>{result.content}</ReactMarkdown>
</div>
{result.metadata && (
<div className="result-metadata">
{Object.entries(result.metadata).map(([key, value]) => (
<span key={key}>{key}: {value}</span>
))}
</div>
)}
</div>
))}
</div>
</div>
);
};
Step 5: Advanced Features Implementation
Implementing Semantic Highlighting
Add this utility function to highlight semantic matches:
export const highlightSemanticMatches = (text, query, semanticWeight) => {
if (!text || !query) return text;
// Simple implementation - in production you'd want to use the API's match data
const queryTerms = query.toLowerCase().split(/\s+/);
const words = text.split(/(\s+)/);
return words.map((word, i) => {
const lowerWord = word.toLowerCase();
const isMatch = queryTerms.some(term =>
lowerWord.includes(term) && term.length > 2
);
return isMatch ? (
<mark key={i} style={{
backgroundColor: `rgba(255, 215, 0, ${semanticWeight})`
}}>
{word}
</mark>
) : word;
});
};
Implementing Hybrid Search Toggle
Enhance the options panel with a hybrid search toggle:
<label>
Hybrid Search:
<input
type="checkbox"
checked={options.hybrid}
onChange={(e) => setOptions({...options, hybrid: e.target.checked})}
/>
</label>
Step 6: Performance Optimization
Implement debouncing for search queries:
import { useCallback, useState, useEffect } from 'react';
import debounce from 'lodash.debounce';
// Inside your component
const [debouncedQuery, setDebouncedQuery] = useState('');
const debouncedSearch = useCallback(
debounce((query) => {
if (query.trim().length > 2) {
mutate({ query, options });
}
}, 500),
[options]
);
useEffect(() => {
debouncedSearch(query);
return () => debouncedSearch.cancel();
}, [query, debouncedSearch]);
Step 7: Error Handling and Retry Logic
Enhance the custom hook with retry capabilities:
export const useDeepSeekSearch = () => {
return useMutation({
mutationFn: ({ query, options }) => search(query, options),
retry: 2,
retryDelay: attemptIndex => Math.min(1000 * 2 ** attemptIndex, 30000),
onError: (error) => {
// Log to error monitoring service
console.error('Search failed:', error);
}
});
};
Step 8: TypeScript Support (Optional)
For TypeScript users, create type definitions:
interface DeepSeekResult {
id: string;
title: string;
content: string;
score: number;
type: 'document' | 'passage' | 'image';
metadata?: Record<string, unknown>;
}
interface DeepSeekOptions {
maxResults?: number;
semanticWeight?: number;
hybrid?: boolean;
filters?: Record<string, string>;
}
interface DeepSeekResponse {
results: DeepSeekResult[];
query_time_ms: number;
total_results: number;
}
Conclusion
This implementation provides a robust integration of DeepSeek R1 into your React application with:
- Proper API client configuration
- React Query for state management
- Configurable search parameters
- Semantic highlighting
- Performance optimizations
- Comprehensive error handling
Remember to:
- Keep your API keys secure using environment variables
- Implement proper rate limiting on the client side
- Monitor API usage and performance
- Consider implementing caching for frequent queries
The DeepSeek R1 API offers additional capabilities like faceted search, custom ranking, and domain-specific tuning that you can explore beyond this basic integration.
🚀 Stop Writing Boilerplate Prompts
If you want to skip the setup and code 10x faster with complete AI architecture patterns, grab my Senior React Developer AI Cookbook ($19). It includes Server Action prompt libraries, UI component generation loops, and hydration debugging strategies.
Browse all 10+ developer products at the Apollo AI Store | Or snipe Solana tokens free via @ApolloSniper_Bot.
Top comments (0)