Documentation/Getting Started/Next.js Quickstart

Next.js Quickstart

Start metering LLM streams in Next.js App Router in under 30 seconds.


Next.js Quickstart

Get real-time token tracking and Stripe billing live in your Next.js application in 4 easy steps.

---

1. Install Package

bash
npm install vibezcheck ai @ai-sdk/openai stripe

---

2. Create Declarative API Route

Create a route handler in `app/api/chat/route.ts`:

typescript
// app/api/chat/route.ts
import { streamText } from 'ai';
import { vibezcheck } from 'vibezcheck';

export const runtime = 'nodejs';
export const dynamic = 'force-dynamic';

export async function POST(req: Request) {
  const { messages, customer = 'demo@example.com' } = await req.json();

  // ⚡ 1-Line Declarative Metering
  return streamText({
    model: vibezcheck('openai/gpt-4o-mini', {
      customer,
      onUsage: (event) => {
        console.log(`⚡ [vibezcheck] Tokens: ${event.usage.totalTokens} | Cost: $${event.cost.totalUSD.toFixed(6)}`);
      },
    }),
    messages,
  }).toTextStreamResponse();
}

---

3. Add React Chat Component

Use `useVibezChat` in `app/page.tsx` to stream responses and sync session telemetry:

tsx
'use client';
import { VibezSessionProvider, useVibezChat, VibezSessionWidget } from 'vibezcheck/react';

function Chat() {
  const { messages, input, handleInputChange, handleSubmit, isLoading } = useVibezChat({
    model: 'gpt-4o-mini',
  });

  return (
    <main className="p-6 max-w-2xl mx-auto">
      <div className="space-y-4 mb-6">
        {messages.map((m) => (
          <div key={m.id} className="p-3 rounded-lg bg-slate-50 border border-slate-200">
            <strong>{m.role === 'user' ? 'You' : 'AI'}:</strong> {m.content}
          </div>
        ))}
      </div>

      <form onSubmit={handleSubmit} className="flex gap-2">
        <input
          value={input}
          onChange={handleInputChange}
          placeholder="Ask anything..."
          className="flex-1 px-4 py-2 border rounded-lg"
        />
        <button type="submit" disabled={isLoading} className="px-4 py-2 bg-black text-white rounded-lg">
          Send
        </button>
      </form>

      {/* Floating live token counter & cost widget */}
      <VibezSessionWidget theme="light" position="bottom-right" />
    </main>
  );
}

export default function App() {
  return (
    <VibezSessionProvider>
      <Chat />
    </VibezSessionProvider>
  );
}