본문으로 건너뛰기

빠른 시작: Svelte

SvelteKit 앱에 AI 채팅을 추가하려고 합니다. 이 가이드를 마치면 TanStack AI와 OpenAI로 구동되는 스트리밍 채팅 컴포넌트를 사용할 수 있습니다.

팁: 개별 AI 제공업체에 가입하고 싶지 않다면 OpenRouter를 사용하면 하나의 API 키로 300개 이상의 모델에 액세스할 수 있어 가장 쉽게 시작할 수 있습니다.

설치

npm install @tanstack/ai @tanstack/ai-svelte @tanstack/ai-openai
# or
pnpm add @tanstack/ai @tanstack/ai-svelte @tanstack/ai-openai
# or
yarn add @tanstack/ai @tanstack/ai-svelte @tanstack/ai-openai

서버 설정

채팅 응답을 스트리밍하는 SvelteKit API 라우트를 생성합니다.

// src/routes/api/chat/+server.ts
import { chat, toServerSentEventsResponse } from '@tanstack/ai'
import { openaiText } from '@tanstack/ai-openai'
import type { RequestHandler } from './$types'

export const POST: RequestHandler = async ({ request }) => {
if (!process.env.OPENAI_API_KEY) {
return new Response(
JSON.stringify({ error: 'OPENAI_API_KEY not configured' }),
{ status: 500, headers: { 'Content-Type': 'application/json' } },
)
}

const body = await request.json()

try {
// `chat()` uses the AG-UI `threadId` for devtools correlation
// when available — no need to plumb `conversationId` manually.
const stream = chat({
adapter: openaiText('gpt-4o'),
messages: body.messages,
})

return toServerSentEventsResponse(stream)
} catch (error) {
return new Response(
JSON.stringify({
error: error instanceof Error ? error.message : 'An error occurred',
}),
{ status: 500, headers: { 'Content-Type': 'application/json' } },
)
}
}

팁: toServerSentEventsResponse는 표준 Response를 반환하므로 Web Response API를 지원하는 모든 서버에서 작동합니다(SvelteKit, Hono, Cloudflare Workers 등).

클라이언트 설정

createChat을 사용하여 Svelte 5 컴포넌트를 생성합니다.

<!-- src/routes/+page.svelte -->
<script lang="ts">
import { createChat, fetchServerSentEvents } from '@tanstack/ai-svelte'

let input = $state('')

const chat = createChat({
connection: fetchServerSentEvents('/api/chat'),
})

function handleSubmit() {
if (input.trim() && !chat.isLoading) {
chat.sendMessage(input)
input = ''
}
}
</script>

<div>
{#each chat.messages as message (message.id)}
<div>
<strong>{message.role === 'assistant' ? 'Assistant' : 'You'}</strong>
{#each message.parts as part}
{#if part.type === 'text'}
<p>{part.content}</p>
{/if}
{/each}
</div>
{/each}

<form onsubmit={handleSubmit}>
<input bind:value={input} placeholder="Type a message..." disabled={chat.isLoading} />
<button type="submit" disabled={!input.trim() || chat.isLoading}>Send</button>
</form>
</div>

환경 변수

API 키가 포함된 .env 파일을 생성합니다.

# OpenRouter (recommended -- access 300+ models with one key)
OPENROUTER_API_KEY=sk-or-...

# OpenAI
OPENAI_API_KEY=your-openai-api-key

SvelteKit 서버는 런타임에 이 키를 읽습니다. 브라우저에 절대 노출하지 마세요.

Svelte 관련 참고 사항

useChat이 아닌 createChat입니다. Svelte 통합은 Svelte의 명명 규칙을 따르기 위해 useChat 대신 createChat을 사용합니다. 반환되는 객체에는 React 및 Vue 버전과 동일한 속성이 있습니다(messages, sendMessage, isLoading, error, status, stop, reload, clear).

Svelte 5 룬. 위 예제에서는 Svelte 5 룬($state)을 사용합니다. createChat이 반환하는 객체는 내부적으로 반응형 getter를 사용하므로 chat.messageschat.isLoading은 별도의 래퍼 없이 반응형입니다. Vue처럼 .value를 사용할 필요도 없고, 언래핑할 signal도 필요하지 않습니다.

자동 정리 없음. React 및 Vue 통합과 달리 createChat은 자동 정리를 등록하지 않습니다. 응답 스트리밍 중 컴포넌트가 언마운트될 수 있다면 onDestroy 콜백에서 chat.stop()을 호출합니다.

<script lang="ts">
import { onDestroy } from 'svelte'
import { createChat, fetchServerSentEvents } from '@tanstack/ai-svelte'

const chat = createChat({
connection: fetchServerSentEvents('/api/chat'),
})

onDestroy(() => {
chat.stop()
})
</script>

이것으로 끝입니다!

이제 작동하는 SvelteKit 채팅 애플리케이션이 완성되었습니다. createChat 함수는 다음을 처리합니다.

  • 메시지 상태 관리
  • 스트리밍 응답
  • 로딩 상태
  • 오류 처리

다음 단계

  • 함수 호출을 추가하려면 도구에 대해 알아봅니다.
  • 다른 제공업체에 연결하려면 어댑터를 확인합니다.
  • 프레임워크를 비교 중이라면 React 빠른 시작을 참고합니다.