alirezasaremi.com logo
alirezasaremi.com logo

Alireza Saremi

Build an AI Customer Support Chatbot with Next.js, Vercel AI SDK and AI Gateway

2026-04-15

AI

In the previous article, we explained Vercel AI SDK and Vercel AI Gateway as architecture concepts. Today we turn that theory into a practical project: an AI customer support chatbot built with Next.js, the AI SDK, and AI Gateway.

This project is simple enough to understand, but real enough to teach important production ideas: streaming responses, support-focused system prompts, model switching, error handling, and a clean separation between the UI and the AI route.

Table of Contents

1. What We Are Going to Build

We will build a small AI chatbot that acts like a customer support assistant. The user can ask questions, and the assistant replies in a helpful and polite way. The response streams to the UI, so the user does not wait for the full answer before seeing anything.

This is a good first practical project because customer support is familiar. Almost every reader has used a support chat before. Also, many businesses can understand the value: faster answers, less repetitive work, and better user experience.

In this version, we will not add a real knowledge base or database yet. The goal is to build the core AI flow first. Later, you can add RAG, documentation search, ticket creation, or user account lookup.

2. Project Architecture

The architecture is simple:

User
 ↓
Chat UI in Next.js
 ↓
/api/chat route
 ↓
Vercel AI SDK
 ↓
Vercel AI Gateway
 ↓
AI model provider

The browser should never call the model provider directly. The browser talks to your own API route. Your API route uses the AI SDK and AI Gateway. This keeps your secret key on the server and gives you one clean place to control the AI behavior.

This is the pattern you should remember: UI for interaction, API route for control, and AI Gateway for model access.

3. Create the Next.js Project

Start with a new Next.js app. You can use npm, pnpm, yarn, or bun. I will use pnpm here:

pnpm create next-app@latest ai-support-chatbot

Then move into the project:

cd ai-support-chatbot

For this article, the App Router is assumed. The important files will be:

app/
  api/
    chat/
      route.ts
  page.tsx
.env.local

4. Install Vercel AI Packages

Now install the AI SDK packages. We need the core ai package, the React helpers, and the AI Gateway provider:

pnpm add ai @ai-sdk/react @ai-sdk/gateway

The ai package gives us functions like streamText. The React package gives us hooks for building the chat UI. The Gateway package lets us route model requests through Vercel AI Gateway.

5. Add the AI Gateway API Key

Create a .env.local file and add your AI Gateway API key:

AI_GATEWAY_API_KEY=your_ai_gateway_key_here

Keep this key on the server. Do not expose it in the browser and do not prefix it with NEXT_PUBLIC_. The API route will use it safely on the server.

After changing environment variables, restart your development server.

6. Build the Chat API Route

Create app/api/chat/route.ts. This route receives the conversation from the UI, sends it to the model, and returns a streaming response.

// app/api/chat/route.ts
import { streamText } from 'ai';
import { gateway } from '@ai-sdk/gateway';

export async function POST(request: Request) {
  const { messages } = await request.json();

  const result = streamText({
    model: gateway('openai/gpt-5.5'),
    system:
      'You are a friendly customer support assistant. Answer clearly, ask follow-up questions when needed, and never invent company policies.',
    messages,
  });

  return result.toUIMessageStreamResponse();
}

There are three important parts here. First, messages contains the chat history. Second, the system prompt tells the model how to behave. Third, toUIMessageStreamResponse() returns a response that the frontend can consume as a stream.

The model name can change later. That is one of the benefits of AI Gateway: your app can move from one model to another with a small change.

7. Build the Chat UI

Now create the UI in app/page.tsx. This is a small interface with message history, an input, and a submit button.

// app/page.tsx
'use client';

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

export default function HomePage() {
  const [input, setInput] = useState('');

  const { messages, append, isLoading } = useChat({
    api: '/api/chat',
  });

  async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
    e.preventDefault();

    if (!input.trim()) return;

    await append({
      role: 'user',
      content: input,
    });

    setInput('');
  }

  return (
    <main className="mx-auto max-w-2xl p-6">
      <h1 className="text-2xl font-bold">AI Customer Support</h1>

      <div className="mt-6 space-y-4 rounded-lg border p-4">
        {messages.length === 0 && (
          <p className="text-sm text-gray-500">
            Ask a support question to start the conversation.
          </p>
        )}

        {messages.map((message) => (
          <div key={message.id}>
            <strong>{message.role === 'user' ? 'You' : 'Support Bot'}:</strong>
            <p>{message.content}</p>
          </div>
        ))}
      </div>

      <form onSubmit={handleSubmit} className="mt-4 flex gap-2">
        <input
          value={input}
          onChange={(e) => setInput(e.target.value)}
          placeholder="Ask about pricing, refunds, or account problems..."
          className="flex-1 rounded-md border px-3 py-2"
        />

        <button
          type="submit"
          disabled={isLoading}
          className="rounded-md bg-black px-4 py-2 text-white disabled:opacity-50"
        >
          {isLoading ? 'Thinking...' : 'Send'}
        </button>
      </form>
    </main>
  );
}

This UI is intentionally simple. The goal is to understand the AI flow first. You can later replace it with shadcn/ui, Tailwind components, markdown rendering, avatars, loading indicators, or a floating chat widget.

8. Make the Bot Behave Like Support

A customer support bot should not behave like a general chatbot. It should be polite, careful, and honest. It should ask questions when information is missing. It should not invent refund rules, delivery times, or account details.

A better system prompt can improve the result:

const supportSystemPrompt = `
You are a customer support assistant for a SaaS product.

Rules:
- Be friendly, short, and clear.
- Ask one follow-up question if the user's issue is unclear.
- Do not invent pricing, refund, legal, or security policies.
- If the issue needs a human, say that you will escalate it.
- Never ask for passwords, secret keys, or full payment card numbers.
`;

Then use it in the API route:

const result = streamText({
  model: gateway('openai/gpt-5.5'),
  system: supportSystemPrompt,
  messages,
});

This is one of the most important lessons in AI product work: the model is only part of the product. The instructions, boundaries, and fallback behavior matter just as much.

9. Add Model Switching

One advantage of AI Gateway is that you can test different models without rewriting the whole app. For example, you can keep a small list of allowed support models:

// app/api/chat/route.ts
const allowedModels = {
  fast: 'openai/gpt-5.5',
  careful: 'anthropic/claude-sonnet-4.6',
} as const;

type ModelKey = keyof typeof allowedModels;

Then read the selected model from the request:

export async function POST(request: Request) {
  const { messages, model = 'fast' } = await request.json();

  const modelKey = model in allowedModels ? (model as ModelKey) : 'fast';

  const result = streamText({
    model: gateway(allowedModels[modelKey]),
    system: supportSystemPrompt,
    messages,
  });

  return result.toUIMessageStreamResponse();
}

This lets you build a UI where users or admins can choose between a fast model and a more careful model. In real products, you may choose the model based on ticket type, user plan, cost, language, or risk level.

10. Add Basic Error Handling

AI requests can fail. The provider may be unavailable, the request may be too large, the user may send unsafe content, or your API key may be missing. A production app should handle these cases.

// app/api/chat/route.ts
export async function POST(request: Request) {
  try {
    const { messages } = await request.json();

    if (!Array.isArray(messages)) {
      return Response.json(
        { error: 'Invalid messages format.' },
        { status: 400 }
      );
    }

    const result = streamText({
      model: gateway('openai/gpt-5.5'),
      system: supportSystemPrompt,
      messages,
    });

    return result.toUIMessageStreamResponse();
  } catch (error) {
    console.error('Chat API error:', error);

    return Response.json(
      { error: 'Something went wrong. Please try again.' },
      { status: 500 }
    );
  }
}

This is not complete production error handling, but it is a good start. You should also log important failures, track usage, and show friendly messages in the UI.

11. What to Improve Next

This chatbot is a solid first version, but a real customer support bot needs more features. Here are the most valuable next steps:

  • RAG: connect the bot to your documentation, FAQ, or help center.
  • Ticket creation: let the bot escalate unresolved issues to a human.
  • User context: show the bot the user plan, account status, or order history.
  • Rate limiting: protect your AI endpoint from abuse and unexpected cost.
  • Observability: monitor cost, latency, failed requests, and model usage.
  • Feedback buttons: let users mark answers as helpful or not helpful.

The important thing is to build in layers. First make the chat work. Then add knowledge. Then add tools. Then add monitoring and cost control.

12. Conclusion

In this article, we built the foundation of an AI customer support chatbot with Next.js, Vercel AI SDK, and AI Gateway. We created a chat API route, streamed responses to the UI, added a support-focused system prompt, and discussed how model switching can help in real products.

The biggest lesson is simple: AI apps are not only about prompts. A good AI product needs architecture. The UI, API route, SDK, gateway, model, safety rules, and future observability all work together.

From here, the natural next step is to connect this chatbot to real knowledge: documentation, FAQs, product data, or support tickets. That is where the chatbot becomes truly useful for users.