Text Delta Handling
Learn how melony automatically handles streaming text updates for smooth user experience.
Overview
melony automatically handles text deltas for smooth streaming. When your server sends incremental text updates, melony joins them together to create a seamless typing effect.
How It Works
Your server streams individual text deltas, and melony automatically combines them:
Server streams deltas
data: {"type": "text-delta", "id": "block1", "delta": "Hello"}
data: {"type": "text-delta", "id": "block1", "delta": " world"}
data: {"type": "text-delta", "id": "block1", "delta": "!"}
Client receives joined text
{type: "text", text: "Hello world!"}
Configuration
Configure delta handling with useMelonyMessages
:
const messages = useMelonyMessages({
joinTextDeltas: {
deltaType: "text-delta",
idField: "id",
deltaField: "delta",
outputType: "text",
outputField: "text",
},
});
Configuration Options
deltaType
- The type field that identifies delta messagesidField
- Field containing the unique identifier for grouping deltasdeltaField
- Field containing the text delta contentoutputType
- The type of the final joined partoutputField
- Field name for the joined text in the outputDefault Behavior
If you don't specify configuration, melony uses these defaults:
// These are the default values
const messages = useMelonyMessages({
joinTextDeltas: {
deltaType: "text-delta",
idField: "id",
deltaField: "delta",
outputType: "text",
outputField: "text",
},
});
Note: The default configuration works with AI SDK's toUIMessageStream()
output format.
Custom Delta Types
You can configure melony to work with different delta formats from your server:
Example: Custom server format
If your server sends deltas in this format:
data: {"type": "chunk", "blockId": "msg-123", "content": "Hello"}
data: {"type": "chunk", "blockId": "msg-123", "content": " world"}
data: {"type": "chunk", "blockId": "msg-123", "content": "!"}
Configure melony accordingly
const messages = useMelonyMessages({
joinTextDeltas: {
deltaType: "chunk",
idField: "blockId",
deltaField: "content",
outputType: "text",
outputField: "text",
},
});
Disabling Delta Handling
If you don't want automatic delta joining, you can disable it:
const messages = useMelonyMessages({
joinTextDeltas: false, // Disable delta handling
});
Note: When disabled, you'll receive individual delta parts as they arrive, and you'll need to handle joining them manually in your UI.
Real-World Example
Here's a complete example showing how text deltas work in practice:
"use client";
import { MelonyProvider, useMelonyMessages } from "melony";
function StreamingChat() {
const messages = useMelonyMessages({
joinTextDeltas: true, // Enable automatic delta joining
});
return (
<div className="chat-container">
{messages.map((message) => (
<div key={message.id} className="message">
<div className="message-role">{message.role}</div>
<div className="message-content">
{message.parts.map((part, i) => (
<div key={i}>
{part.type === "text" && (
<p className="streaming-text">{part.text}</p>
)}
</div>
))}
</div>
</div>
))}
</div>
);
}
export default function Chat() {
return (
<MelonyProvider endpoint="/api/chat">
<StreamingChat />
</MelonyProvider>
);
}
Troubleshooting
Deltas not joining
Check that your server is sending the correct format and that the configuration matches your server's delta structure.
Multiple text parts
If you see multiple text parts instead of joined text, verify that theidField
values match for deltas that should be joined.