Technology Apr 15, 2026 · 5 min read

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...

DE
DEV Community
by Apollo
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

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:

  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.

DE
Source

This article was originally published by DEV Community and written by Apollo.

Read original article on DEV Community
Back to Discover

Reading List