
# Stream Text with Image Prompt

Vision models such as GPT-4 can process both text and images. In this example, we will show you how to send an image URL along with the user's message to the model.

## Using Image URLs

### Server

We split the user's message into two parts: the text and the image URL. We then send both parts to the model.
The last message is the user's message, and we add the image URL to it.

```tsx filename='app/api/chat/route.ts' highlight="8,9,23"
import { openai } from '@ai-sdk/openai';
import { streamText } from 'ai';

export const maxDuration = 60;

export async function POST(req: Request) {
  // 'data' contains the additional data that you have sent:
  const { messages, data } = await req.json();

  const initialMessages = messages.slice(0, -1);
  const currentMessage = messages[messages.length - 1];

  // Call the language model
  const result = streamText({
    model: openai('gpt-4-turbo'),
    messages: [
      ...initialMessages,
      {
        role: 'user',
        content: [
          { type: 'text', text: currentMessage.content },
          { type: 'image', image: new URL(data.imageUrl) },
        ],
      },
    ],
  });

  // Respond with the stream
  return result.toDataStreamResponse();
}
```

### Client

On the client we can send the image URL along with the user's message by adding the `data` object to the `handleSubmit` function.
You can replace the `imageUrl` with the actual URL of the image you want to send.

```typescript filename='app/page.tsx' highlight="18-20"
'use client';

import { useChat } from '@ai-sdk/react';

// Allow streaming responses up to 30 seconds
export const maxDuration = 30;

export default function Chat() {
  const { messages, input, handleInputChange, handleSubmit } = useChat();
  return (
    <div>
      {messages.map(m => (
        <div key={m.id}>
          {m.role === 'user' ? 'User: ' : 'AI: '}
          {m.content}
        </div>
      ))}

      <form
        onSubmit={e => {
          handleSubmit(e, {
            data: { imageUrl: 'https://somewhere.com/image.png' },
          });
        }}
      >
        <input
          value={input}
          placeholder="What does the image show..."
          onChange={handleInputChange}
        />
      </form>
    </div>
  );
}
```


## Navigation

- [Generate Text](/v4/cookbook/next/generate-text)
- [Generate Text with Chat Prompt](/v4/cookbook/next/generate-text-with-chat-prompt)
- [Generate Image with Chat Prompt](/v4/cookbook/next/generate-image-with-chat-prompt)
- [Stream Assistant Response](/v4/cookbook/next/stream-assistant-response)
- [Stream Assistant Response with Tools](/v4/cookbook/next/stream-assistant-response-with-tools)
- [Caching Middleware](/v4/cookbook/next/caching-middleware)
- [Stream Text](/v4/cookbook/next/stream-text)
- [Stream Text with Chat Prompt](/v4/cookbook/next/stream-text-with-chat-prompt)
- [Stream Text with Image Prompt](/v4/cookbook/next/stream-text-with-image-prompt)
- [Chat with PDFs](/v4/cookbook/next/chat-with-pdf)
- [streamText Multi-Step Cookbook](/v4/cookbook/next/stream-text-multistep)
- [Markdown Chatbot with Memoization](/v4/cookbook/next/markdown-chatbot-with-memoization)
- [Generate Object](/v4/cookbook/next/generate-object)
- [Generate Object with File Prompt through Form Submission](/v4/cookbook/next/generate-object-with-file-prompt)
- [Stream Object](/v4/cookbook/next/stream-object)
- [Call Tools](/v4/cookbook/next/call-tools)
- [Call Tools in Parallel](/v4/cookbook/next/call-tools-in-parallel)
- [Call Tools in Multiple Steps](/v4/cookbook/next/call-tools-multiple-steps)
- [Model Context Protocol (MCP) Tools](/v4/cookbook/next/mcp-tools)
- [Human-in-the-Loop with Next.js](/v4/cookbook/next/human-in-the-loop)
- [Send Custom Body from useChat](/v4/cookbook/next/send-custom-body-from-use-chat)
- [Render Visual Interface in Chat](/v4/cookbook/next/render-visual-interface-in-chat)


[Full Sitemap](/sitemap.md)
