n4nAI

Vercel AI SDK useChat with n4n.ai: full walkthrough

Hands-on vercel ai sdk usechat n4n.ai walkthrough: build a streaming Next.js chat UI on an OpenAI-compatible gateway with fallback and per-token metering.

n4n Team2 min read391 words

Audio narration

Coming soon — every post will get a voice note here.

This vercel ai sdk usechat n4n.ai walkthrough gets a streaming chat interface running on Next.js in about fifteen minutes. We wire useChat to an OpenAI-compatible inference gateway that addresses 240+ models and fails over automatically when a provider is rate-limited.

Prerequisites

  • Node.js 18+ and a package manager (npm/pnpm).
  • A Next.js 14+ app using the App Router. If you don’t have one, npx create-next-app@latest chat-app and accept defaults.
  • Install the Vercel AI SDK packages:
npm install ai @ai-sdk/openai @ai-sdk/react
  • An API key for the gateway. Put it in .env.local:
N4N_API_KEY=sk-xxxx

Step 1: Server route with streamText

Create app/api/chat/route.ts. The route parses messages and streams tokens back using the AI SDK’s streamText. Point the OpenAI provider at the gateway’s /v1 base URL.

import { openai } from '@ai-sdk/openai';
import { streamText } from 'ai';

export const runtime = 'edge';

const gateway = openai({
  baseURL: 'https://api.n4n.ai/v1',
  apiKey: process.env.N4N_API_KEY!,
});

export async function POST(req: Request) {
  const { messages } = await req.json();
  const result = await streamText({
    model: gateway('openai/gpt-4o-mini'),
    messages,
  });
  return result.toDataStreamResponse();
}

Model IDs follow the provider/model convention. Swap openai/gpt-4o-mini for any of the 240+ available models without changing client code.

Step 2: Client component with useChat

The useChat hook manages message state, input, and submission. Create app/Chat.tsx as a client component.

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

export default function Chat() {
  const { messages, input, handleInputChange, handleSubmit, isLoading } =
    useChat();

  return (
    <div style={{ maxWidth: 600, margin: '0 auto' }}>
      {messages.map((m) => (
        <div key={m.id} style={{ margin: '0.5rem 0' }}>
          <strong>{m.role}:</strong> {m.content}
        </div>
      ))}
      {isLoading && <div>…streaming</div>}
      <form onSubmit={handleSubmit}>
        <input
          value={input}
          onChange={handleInputChange}
          placeholder="Say something"
          style={{ width: '80%' }}
        />
        <button type="submit">Send</button>
      </form>
    </div>
  );
}

Mount it in app/page.tsx:

import Chat from './Chat';

export default function Page() {
  return (
    <main>
      <h1>Streaming Chat</h1>
      <Chat />
    </main>
  );
}

Step 3: Run and verify streaming

Start the dev server:

npm run dev

Open http://localhost:3000. Type Explain recursion in one sentence and submit. You should see the user message appear immediately, then the assistant message render token-by-token.

Expected messages shape after completion:

[
  { "id": "1", "role": "user", "content": "Explain recursion in one sentence" },
  { "id": "2", "role": "assistant", "content": "Recursion is a function that calls itself to solve smaller instances of the same problem." }
]

If you see a 401, check N4N_API_KEY. A 404 on the model means the ID is wrong—list available models from the gateway’s /v1/models endpoint.

Step 4: Capture usage and rely on fallback

This vercel ai sdk usechat n4n.ai walkthrough leverages per-token usage metering exposed by the gateway. The AI SDK surfaces final usage in onFinish. Extend the route:

return result.toDataStreamResponse({
  onFinish: ({ usage }) => {
    // usage: { promptTokens, completionTokens, totalTokens }
    console.log('metering', usage);
  },
});

No client changes are required to benefit from automatic fallback. When the primary provider behind a model is degraded or rate-limited, the gateway routes to a healthy equivalent and the stream continues. Your useChat UI treats it as a normal response.

Step 5: Production hardening

useChat sends the full message history each request. For long sessions, trim server-side or summarize. Add error handling in the client:

const { error, reload } = useChat();
{error && <button onClick={reload}>Retry</button>}

Set export const maxDuration = 30; in the route for Vercel’s edge function timeout. Keep the API key server-side only—never expose it to the client.

For caching, the gateway forwards provider cache-control hints when you pass them through the request body’s standard extensions field. The AI SDK lets you inject extra body fields via the body option in streamText:

streamText({
  model: gateway('anthropic/claude-3-haiku'),
  messages,
  body: { extensions: { cache_control: { type: 'ephemeral' } } },
});

That’s the full loop: a typed React UI, a thin Next.js route, and a gateway that handles model breadth, failover, and metering. The useChat contract stays identical regardless of which backend model answers.

Tagsvercel-ai-sdkusechatn4n-aiwalkthrough

Written by

n4n Team

The team building n4n — a single OpenAI-compatible API in front of 240+ models, with automatic fallback, load balancing and pay-per-token metering.

More from n4n Team →

All vercel ai sdk streaming chat ui (usechat) posts →