Basic Next.js AI Chat
Want to view the full code? Check out the basic-nextjs-ai-chat repository on GitHub.
Create a new Next.js project
Next.js recommends starting a new Next.js app using create-next-app
, which sets up everything automatically for you. To create a project, run:
npx create-next-app@latest
Accept all the defaults.
Environment Variables
Create .env.local
file in the root of your project and add the following variables:
OPENAI_API_KEY=xxxxxx
INVSY_API_KEY=xxxxxx
INVSY_PROJECT_ID=xxxxxx
Get your Invsy secret key and project ID from the Invsy dashboard
Install packages & create the Invsy instance
Install the invsy
, ai
and @ai-sdk/openai
SDKs by running:
npm add invsy ai @ai-sdk/openai
Then create the Invsy instance in a new file ./src/libs/invsy.ts
:
import { Invsy } from "invsy"
// Add your own auth logic
export const userId = "user1"
export const invsy = new Invsy({
token: process.env.INVSY_API_KEY!,
projectId: process.env.INVSY_PROJECT_ID!,
userId
})
Update the root page
Replace the contents of ./src/page.tsx
with the following code:
import { invsy } from "@/libs/invsy";
import { redirect } from "next/navigation";
export default async function Page() {
// Create new chat and returns the chat id
const { id } = await invsy.create({
title: "new chat"
})
redirect(`/${id}`)
}
Create the ChatUI
component
"use client"
import { useChat } from "ai/react";
import { InvsyChat } from "invsy";
type Props = {
chat: InvsyChat
}
export const ChatUi = ({ chat }: Props) => {
const { messages, input, handleInputChange, handleSubmit } = useChat({
api: `/api/chat/${chat.id}`,
keepLastMessageOnError: true,
initialMessages: chat.messages ? chat.messages : [],
});
return (
<>
{messages.map((message, index) => (
<div key={index}>
{message.role === 'user' ? 'User: ' : 'AI: '}
{message.content}
</div>
))}
<form onSubmit={handleSubmit}>
<input name="prompt" value={input} onChange={handleInputChange} />
<button type="submit">Submit</button>
</form>
</>
);
}
Create the chat page
Create a new file ./src/app/[chat_id]/page.tsx
and add the following code:
import { ChatUi } from "@/components/chat-ui";
import { invsy } from "@/libs/invsy";
type Props = {
params: {
chat_id: string;
};
}
export default async function ChatPage({params}: Props) {
const chatId = params.chat_id
const chat = await invsy.get(chatId);
return (
<>
<ChatUi chat={chat}/>
</>
);
}
Create the chat API
Create a new file ./src/app/api/chat/[chat_id]/route.ts
and add the following code:
import {createOpenAI, openai} from '@ai-sdk/openai';
import { convertToCoreMessages, streamText } from 'ai';
import { invsy } from "@/libs/invsy";
import { InvsyChatPartial } from "invsy";
// Allow streaming responses up to 30 seconds
export const maxDuration = 30;
export async function POST(req: Request, { params }: { params: { chat_id: string } }) {
const { messages } = await req.json();
const openai = createOpenAI({
apiKey: process.env.OPENAI_API_KEY,
baseURL: process.env.OPENAI_API_BASE
})
const result = await streamText({
model: openai('gpt-4-turbo'),
system: 'You are a helpful assistant.',
messages: convertToCoreMessages(messages),
// You can determine message role by checking toolCalls, toolResults etc.
async onFinish({ text, toolCalls, toolResults }) {
messages.push({
role: 'assistant',
content: text
})
const payload: InvsyChatPartial = {
id: params.chat_id,
messages
}
// Update the chat title
if (messages.length <= 2) {
payload.meta = {
// Get the content of the first message and limit to 100 chars
title: messages[0].content.slice(0, 100),
}
}
await invsy.save(payload);
},
});
return result.toDataStreamResponse();
}
Run npm run dev
and navigate to http://localhost:3000
in your browser. Add a prompt in the input field and click submit. You should see the AI response in the chat window.
Refresh the page and you should see the chat history!
Congradulations! You have successfully created a basic AI chat app using Next.js and Invsy. You can now customize the chat UI and add more features to your app.