Skip to content

Instantly share code, notes, and snippets.

@domitriusclark
Created December 17, 2025 20:55
Show Gist options
  • Select an option

  • Save domitriusclark/d0e4995b67312d45473ae3a054434919 to your computer and use it in GitHub Desktop.

Select an option

Save domitriusclark/d0e4995b67312d45473ae3a054434919 to your computer and use it in GitHub Desktop.
// components/Chat.tsx
import { useState } from "react";
import { useChat, fetchServerSentEvents } from "@tanstack/ai-react";
export function Chat() {
const [input, setInput] = useState("");
const { messages, sendMessage, isLoading } = useChat({
connection: fetchServerSentEvents("/api/chat"),
});
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
if (input.trim() && !isLoading) {
sendMessage(input);
setInput("");
}
};
return (
<div className="flex flex-col h-screen">
{/* Messages */}
<div className="flex-1 overflow-y-auto p-4">
{messages.map((message) => (
<div
key={message.id}
className={`mb-4 ${message.role === "assistant" ? "text-blue-600" : "text-gray-800"
}`}
>
<div className="font-semibold mb-1">
{message.role === "assistant" ? "Assistant" : "You"}
</div>
<div>
{message.parts.map((part, idx) => {
if (part.type === "thinking") {
return (
<div
key={idx}
className="text-sm text-gray-500 italic mb-2"
>
💭 Thinking: {part.content}
</div>
);
}
if (part.type === "text") {
return <div key={idx}>{part.content}</div>;
}
return null;
})}
</div>
</div>
))}
</div>
{/* Input */}
<form onSubmit={handleSubmit} className="p-4 border-t">
<div className="flex gap-2">
<input
type="text"
value={input}
onChange={(e) => setInput(e.target.value)}
placeholder="Type a message..."
className="flex-1 px-4 py-2 border rounded-lg"
disabled={isLoading}
/>
<button
type="submit"
disabled={!input.trim() || isLoading}
className="px-6 py-2 bg-blue-600 text-white rounded-lg disabled:opacity-50"
>
Send
</button>
</div>
</form>
</div>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment