DEV Community

Apollo
Apollo

Posted on

How to integrate DeepSeek R1 into your React app

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
Enter fullscreen mode Exit fullscreen mode

Install required dependencies:

npm install axios @tanstack/react-query react-markdown
Enter fullscreen mode Exit fullscreen mode

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;
  }
};
Enter fullscreen mode Exit fullscreen mode

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);
    }
  });
};
Enter fullscreen mode Exit fullscreen mode

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>
  );
};
Enter fullscreen mode Exit fullscreen mode

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;
  });
};
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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]);
Enter fullscreen mode Exit fullscreen mode

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);
    }
  });
};
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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:

  1. Keep your API keys secure using environment variables
  2. Implement proper rate limiting on the client side
  3. Monitor API usage and performance
  4. 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)