AI-чат на React через AI Gateway: запросы к своему бэкенду
Как сделать чат-компонент на React с AI Gateway правильно: React ходит в ваш backend-прокси, а ключ живёт только на сервере. Пример компонента и потокового вывода ответа.
Чат-компонент на 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. Компонент ниже работает с любым таким эндпоинтом.
Реализация
- Простой чат-компонент
Отправляем сообщение на свой прокси
/api/chatи показываем ответ. Ключа здесь нет — только вызов собственного бэкенда:tsxtsximport { 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>);} - Потоковый вывод ответа
Если прокси стримит ответ (
text/plainили SSE), читаем тело как поток и дописываем текст по мере поступления — так ответ «печатается»:tsxtsxasync 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));}}
Какие модели подойдут
Модель выбирается на сервере, а не в компоненте. Для интерактивного чата важна скорость первого токена — обычно берут быструю модель, оставляя флагман для сложных запросов:
Частые вопросы
Почему нельзя обращаться к AI Gateway прямо из React?
Код фронтенда доступен любому пользователю, а значит и ключ, вшитый в бандл. Его тут же используют посторонние, и весь расход ляжет на вас. Ключ должен оставаться на сервере, а браузер обращается к вашему прокси.
А если у меня чисто фронтенд без бэкенда?
Тогда прокси-эндпоинт можно поднять как serverless-функцию (Vercel, Cloudflare Workers, Netlify Functions) — это несколько строк кода, а ключ остаётся в переменных окружения платформы.
Как хранить историю диалога?
Держите массив сообщений в состоянии компонента и передавайте его в теле запроса на прокси; собирать финальный messages для модели должен сервер. Старые сообщения обрезайте, чтобы экономить токены.