Интеграции

AI-чат на React через AI Gateway: запросы к своему бэкенду

Как сделать чат-компонент на React с AI Gateway правильно: React ходит в ваш backend-прокси, а ключ живёт только на сервере. Пример компонента и потокового вывода ответа.

2 минуты чтения

Чат-компонент на React не должен обращаться к API модели напрямую: код фронтенда виден пользователю, и ключ утечёт. Правильная схема — React шлёт сообщение в ваш собственный backend-прокси, а тот уже ходит в AI Gateway с ключом. Ниже — компонент и вариант с потоковым выводом ответа.

Никогда не кладите ключ sk-aigate-… в код React или в переменные с префиксом VITE_/NEXT_PUBLIC_ — всё это попадает в бандл браузера и легко читается. Ключ хранится только на сервере, а React обращается к вашему эндпоинту-прокси (например, Next.js route handler или FastAPI).

Подготовка

На стороне сервера настройте эндпоинт (/api/chat), который принимает текст, обращается к https://ai-gatewey.ru/v1 с ключом из окружения и возвращает ответ. Готовые примеры прокси: Next.js и FastAPI. Компонент ниже работает с любым таким эндпоинтом.

Реализация

  1. Простой чат-компонент

    Отправляем сообщение на свой прокси /api/chat и показываем ответ. Ключа здесь нет — только вызов собственного бэкенда:

    import { useState } from "react";
    
    export function Chat() {
      const [input, setInput] = useState("");
      const [reply, setReply] = useState("");
      const [loading, setLoading] = useState(false);
    
      async function send() {
        setLoading(true);
        const res = await fetch("/api/chat", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ message: input }),
        });
        const data = await res.json();
        setReply(data.reply);
        setLoading(false);
      }
    
      return (
        <div>
          <textarea value={input} onChange={(e) => setInput(e.target.value)} />
          <button onClick={send} disabled={loading}>
            Отправить
          </button>
          <p>{reply}</p>
        </div>
      );
    }
  2. Потоковый вывод ответа

    Если прокси стримит ответ (text/plain или SSE), читаем тело как поток и дописываем текст по мере поступления — так ответ «печатается»:

    async function sendStream() {
      const res = await fetch("/api/chat", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ message: input }),
      });
    
      const reader = res.body!.getReader();
      const decoder = new TextDecoder();
      setReply("");
      for (;;) {
        const { value, done } = await reader.read();
        if (done) break;
        setReply((prev) => prev + decoder.decode(value));
      }
    }

Какие модели подойдут

Модель выбирается на сервере, а не в компоненте. Для интерактивного чата важна скорость первого токена — обычно берут быструю модель, оставляя флагман для сложных запросов:

МодельВвод, ₽/1МВывод, ₽/1МКонтекст
DeepSeek: DeepSeek V331125128K
OpenAI: GPT-5.4 Mini118705400K
Anthropic Claude Haiku Latest157784200K
Актуальные цены каталога AI Gateway за 1 млн токенов. Все модели →

Частые вопросы

Почему нельзя обращаться к AI Gateway прямо из React?

Код фронтенда доступен любому пользователю, а значит и ключ, вшитый в бандл. Его тут же используют посторонние, и весь расход ляжет на вас. Ключ должен оставаться на сервере, а браузер обращается к вашему прокси.

А если у меня чисто фронтенд без бэкенда?

Тогда прокси-эндпоинт можно поднять как serverless-функцию (Vercel, Cloudflare Workers, Netlify Functions) — это несколько строк кода, а ключ остаётся в переменных окружения платформы.

Как хранить историю диалога?

Держите массив сообщений в состоянии компонента и передавайте его в теле запроса на прокси; собирать финальный messages для модели должен сервер. Старые сообщения обрезайте, чтобы экономить токены.

Чат на React с AI — начните с ключа на сервере

Получить ключ