useChat와 함께 커스텀 headers, body, credentials가 동작하지 않을 때
useChat와 함께 커스텀 headers, body, credentials가 동작하지 않을 때
useChat 훅에 직접 설정한 headers, body, credentials 같은 커스텀 요청 옵션이 요청에 포함되지 않는 경우가 있어요. 이유와 해결 방법을 정리해 드릴게요.
출처: 문서
본문
문제 (Issue)
useChat 훅을 사용할 때 훅에 직접 설정한 headers, body 필드, credentials 같은 커스텀 요청 옵션이 요청에 함께 전송되지 않습니다.
// These options are not sent with the request
const { messages, sendMessage } = useChat({
headers: {
Authorization: 'Bearer token123',
},
body: {
user_id: '123',
},
credentials: 'include',
});
배경 (Background)
useChat 훅은 요청 옵션을 설정하는 API가 변경되었습니다. 훅 자체에 직접 설정하는 headers, body, credentials 같은 옵션은 더 이상 지원되지 않습니다. 대신 DefaultChatTransport와 함께 transport 설정을 사용하거나 요청 레벨에서 옵션을 전달해야 합니다.
해결책 (Solution)
useChat로 요청 옵션을 제대로 설정하는 방법은 세 가지가 있습니다.
옵션 1: 요청 레벨 설정 (동적 값에 권장)
시간이 지남에 따라 변하는 동적 값에는 sendMessage를 호출할 때 옵션을 전달하는 방식이 권장됩니다.
const { messages, sendMessage } = useChat();
// Send options with each message
sendMessage(
{ text: input },
{
headers: {
Authorization: *** ${getAuthToken()}`, // Dynamic auth token
'X-Request-ID': generateRequestId(),
},
body: {
temperature: 0.7,
max_tokens: 100,
user_id: getCurrentUserId(), // Dynamic user ID
sessionId: getCurrentSessionId(), // Dynamic session
},
},
);
이 방식은 각 요청에 항상 가장 최신 값을 보낼 수 있게 해 줍니다.
옵션 2: 정적 값을 가진 훅 레벨 설정
컴포넌트 수명 동안 변하지 않는 정적 값에는 DefaultChatTransport를 사용하세요.
import { useChat } from '@ai-sdk/react';
import { DefaultChatTransport } from 'ai';
const { messages, sendMessage } = useChat({
transport: new DefaultChatTransport({
api: '/api/chat',
headers: {
'X-API-Version': 'v1', // Static API version
'X-App-ID': 'my-app', // Static app identifier
},
body: {
model: 'gpt-6-astra', // Default model
stream: true, // Static configuration
},
credentials: 'include', // Static credentials policy
}),
});
옵션 3: 함수(Resolvable) 형식의 훅 레벨 설정
훅 레벨에서 동적 값이 필요하다면 설정 값을 반환하는 함수를 사용할 수 있습니다. 다만 신뢰성 면에서는 요청 레벨 설정이 일반적으로 더 선호됩니다.
import { useChat } from '@ai-sdk/react';
import { DefaultChatTransport } from 'ai';
const { messages, sendMessage } = useChat({
transport: new DefaultChatTransport({
api: '/api/chat',
headers: () => ({
Authorization: *** ${getAuthToken()}`,
'X-User-ID': getCurrentUserId(),
}),
body: () => ({
sessionId: getCurrentSessionId(),
preferences: getUserPreferences(),
}),
credentials: () => (isAuthenticated() ? 'include' : 'same-origin'),
}),
});
훅 레벨과 요청 레벨 옵션 결합
요청 레벨 옵션은 훅 레벨 옵션보다 우선합니다.
// Hook-level default configuration
const { messages, sendMessage } = useChat({
transport: new DefaultChatTransport({
api: '/api/chat',
headers: {
'X-API-Version': 'v1',
},
body: {
model: 'gpt-6-astra',
},
}),
});
// Override or add options per request
sendMessage(
{ text: input },
{
headers: {
'X-API-Version': 'v2', // This overrides the hook-level header
'X-Request-ID': '123', // This is added
},
body: {
model: 'gpt-4.1-mini', // Supports the temperature setting below
temperature: 0.5, // This is added
},
},
);
요청 구성에 대한 자세한 내용은 Request Configuration 문서를 참고하세요.
더 알아보기 (Learn more)
- AI SDK 공식 문서에서 다른 트러블슈팅 항목도 확인해 보세요.