GitHub Repository You can find the project source code on GitHub.
This guide provides detailed, step-by-step instructions on how to use Upstash RAG Chat with Next.js. You can also explore our Next.js Chat to Website example for detailed, end-to-end examples and best practices.
Project Setup
Create a new Next.js application and install @upstash/rag-chat
package.
npx create-next-app@latest
cd my-app
npm install @upstash/rag-chat
Setup Upstash Redis
Create a Redis database using Upstash Console or Upstash CLI and copy the UPSTASH_REDIS_REST_URL
and UPSTASH_REDIS_REST_TOKEN
into your .env
file.
UPSTASH_REDIS_REST_URL = < YOUR_URL>
UPSTASH_REDIS_REST_TOKEN = < YOUR_TOKEN>
Setup Upstash Vector
Create a Vector index using Upstash Console or Upstash CLI and copy the UPSTASH_VECTOR_REST_URL
and UPSTASH_VECTOR_REST_TOKEN
into your .env
file.
UPSTASH_VECTOR_REST_URL = < YOUR_URL>
UPSTASH_VECTOR_REST_TOKEN = < YOUR_TOKEN>
Setup QStash LLM
Navigate to QStash Console and copy the QSTASH_TOKEN
into your .env
file.
QSTASH_TOKEN = < YOUR_TOKEN>
Create a middleware in /app/middleware.ts
to generate a session ID cookie. This cookie will be used to track the user’s chat session.
import { NextRequest, NextResponse } from "next/server" ;
export function middleware ( req: NextRequest) {
const res = NextResponse. next ( ) ;
const cookie = req. cookies. get ( "sessionId" ) ;
if ( ! cookie) {
res. cookies. set ( "sessionId" , crypto. randomUUID ( ) ) ;
}
return res;
}
Create a Chat Streaming API Route
We will create a RAG Chat instance in /app/lib/rag-chat.ts
to later use in our API route and Home page.
import { RAGChat, upstash } from "@upstash/rag-chat" ;
import { Redis } from "@upstash/redis" ;
const redis = Redis. fromEnv ( ) ;
export const ragChat = new RAGChat ( {
model: upstash ( "meta-llama/Meta-Llama-3-8B-Instruct" ) ,
redis: redis,
} ) ;
Using the RAG Chat instance we created, we can now create a chat streaming API route in /app/api/chat-stream/route.ts
.
/app/api/chat-stream/route.ts
import { ragChat } from "@/app/lib/rag-chat" ;
import { aiUseChatAdapter } from "@upstash/rag-chat/nextjs" ;
import { NextRequest } from "next/server" ;
export const POST = async ( req: NextRequest) => {
const { messages, sessionId } = await req. json ( ) ;
const lastMessage = messages[ messages. length - 1 ] . content;
const response = await ragChat. chat ( lastMessage, {
streaming: true ,
sessionId,
} ) ;
return aiUseChatAdapter ( response) ;
} ;
Create a Chat Component
We can now create a chat component in /app/components/chat.tsx
using the chat streaming API route we created.
"use client" ;
import { useChat, Message } from "ai/react" ;
export const Chat = ( {
sessionId,
initialMessages,
} : {
sessionId: string ;
initialMessages: Message[ ] ;
} ) => {
const { messages, handleInputChange, handleSubmit, input, setInput } =
useChat ( {
api: "/api/chat-stream" ,
body: { sessionId } ,
initialMessages,
} ) ;
return (
< div>
< div className= "flex h-[calc(100vh-64px)] flex-col overflow-y-auto items-center" >
{ messages. length ? (
messages. map ( ( message, i) => (
< div className= "w-[60vw] flex flex-row gap-3 p-6" key= { i} >
< div className= "min-w-12" >
{ message. role === "user" ? "User" : "Bot" }
< / div>
< p className= "text-sm font-normal text-gray-900" >
{ message. content}
< / p>
< / div>
) )
) : (
< div className= "text-zinc-500 text-sm pt-6" >
Ask your first question to get started.
< / div>
) }
< / div>
< form onSubmit= { handleSubmit} className= "relative" >
< div className= "flex flex-row gap-2 p-3 h-16 items-center" >
< input
onChange= { handleInputChange}
value= { input}
onKeyDown= { ( e) => {
if ( e. key === "Enter" && ! e. shiftKey) {
e. preventDefault ( ) ;
handleSubmit ( ) ;
setInput ( "" ) ;
}
} }
placeholder= "Enter your question..."
className= "border rounded-xl w-full py-1 px-3"
/ >
< button type= "submit" className= "border rounded-xl py-1 px-3" >
Send
< / button>
< / div>
< / form>
< / div>
) ;
} ;
Update Home Page
Update /app/page.tsx
using the Chat component we created.
import { Chat } from "./components/chat" ;
import { cookies } from "next/headers" ;
import { ragChat } from "@/app/lib/rag-chat" ;
export default async function Home ( ) {
const sessionId = cookies ( ) . get ( "sessionId" ) ?. value;
const initialMessages = await ragChat. history . getMessages ( {
amount: 10 ,
sessionId,
} ) ;
return < Chat sessionId = { sessionId! } initialMessages = { initialMessages} /> ;
}
Run & Deploy
Run the app locally with npm run dev
, check http://localhost:3000/
Deploy your app with vercel