Skip to content

Commit b115d0f

Browse files
committed
📦 NEW: add nextjs app guide
1 parent b05ee94 commit b115d0f

File tree

2 files changed

+386
-2
lines changed

2 files changed

+386
-2
lines changed
Lines changed: 380 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,380 @@
1+
---
2+
title: "Build a Next.js App with BaseAI"
3+
description: "Learn how to build a Next.js app with BaseAI"
4+
tags:
5+
- nextjs
6+
- baseai
7+
- langbase
8+
- guide
9+
section: 'guides'
10+
published: 2024-09-30
11+
modified: 2024-09-30
12+
---
13+
14+
# Build a Next.js App with BaseAI
15+
16+
This guide covers building AI features in a Next.js app using BaseAI, focusing on text summarization with the BaseAI pipe.
17+
18+
---
19+
20+
## Next.js with BaseAI Example
21+
22+
We also have pre-built a Next.js app with BaseAI for you to get started quickly. You can refer to the following resources to understand how to build a Next.js app with BaseAI.
23+
24+
- [Next.js with BaseAI](https://github.com/LangbaseInc/baseai/tree/main/examples/nextjs)
25+
- [Example of using BaseAI](https://github.com/LangbaseInc/baseai/tree/main/examples/nextjs/app/demo)
26+
- [BaseAI based React components](https://github.com/LangbaseInc/baseai/tree/main/examples/nextjs/components)
27+
- [API Route handlers for pipes](https://github.com/LangbaseInc/baseai/tree/main/examples/nextjs/app/api/langbase/pipes)
28+
29+
30+
### AI Agent Pipe: Run
31+
32+
- [React Component](https://github.com/LangbaseInc/baseai/blob/main/examples/nextjs/components/pipe-run.tsx)
33+
- [API Route Handler](https://github.com/LangbaseInc/baseai/blob/main/examples/nextjs/app/api/langbase/pipes/run/route.ts)
34+
35+
### AI Agent Pipe: Stream
36+
37+
- [React Component](https://github.com/LangbaseInc/baseai/blob/main/examples/nextjs/components/pipe-stream.tsx)
38+
- [API Route Handler](https://github.com/LangbaseInc/baseai/blob/main/examples/nextjs/app/api/langbase/pipes/run-stream/route.ts)
39+
40+
### `usePipe()`: Chat
41+
42+
- [React Component](https://github.com/LangbaseInc/baseai/blob/main/examples/nextjs/components/chat-simple.tsx)
43+
- [API Route Handler](https://github.com/LangbaseInc/baseai/blob/main/examples/nextjs/app/api/langbase/pipes/run-stream/route.ts)
44+
45+
### `usePipe()`: Chat Advanced
46+
47+
- [React Component](https://github.com/LangbaseInc/baseai/blob/main/examples/nextjs/components/chat-advanced.tsx)
48+
- [API Route Handler](https://github.com/LangbaseInc/baseai/blob/main/examples/nextjs/app/api/langbase/pipes/run-stream/route.ts)
49+
50+
### AI Agent Pipes: Tool Calling
51+
52+
- [React Component](https://github.com/LangbaseInc/baseai/blob/main/examples/nextjs/components/pipe-run-with-tool.tsx)
53+
- [API Route Handler](https://github.com/LangbaseInc/baseai/blob/main/examples/nextjs/app/api/langbase/pipes/run-tool/route.ts)
54+
55+
### AI Agent Pipes: Composable Pipe Run
56+
57+
- [React Component](https://github.com/LangbaseInc/baseai/blob/main/examples/nextjs/components/pipe-run-pipes-as-tools.tsx)
58+
- [API Route Handler](https://github.com/LangbaseInc/baseai/blob/main/examples/nextjs/app/api/langbase/pipes/run-pipes-as-tools/route.ts)
59+
60+
### AI Agent Pipes: Memory
61+
62+
- [React Component](https://github.com/LangbaseInc/baseai/blob/main/examples/nextjs/components/pipe-run-with-memory.tsx)
63+
- [API Route Handler](https://github.com/LangbaseInc/baseai/blob/main/examples/nextjs/app/api/langbase/pipes/run-memory/route.ts)
64+
65+
---
66+
67+
## Step #1: Install Next.js
68+
69+
First, you need to install Next.js in your project directory.
70+
71+
```bash
72+
npx create-next-app@latest nextjs-baseai-app
73+
```
74+
75+
Also setup tailwind in your Next.js app. You can use the setup from the [Next.js with BaseAI example](https://github.com/LangbaseInc/baseai/tree/main/examples/nextjs).
76+
77+
---
78+
79+
## Step #2: Install BaseAI
80+
81+
Next, you need to install BaseAI in your project directory.
82+
83+
```bash
84+
npx baseai@latest init
85+
```
86+
---
87+
88+
## Step #3: Create a Summary Pipe
89+
90+
Create a new pipe using the `pipe` command. Use `summary` as the pipe name and for system prompt use `You are a helpful AI assistant. Make everything Less wordy.`.
91+
92+
```bash
93+
npx baseai@latest pipe
94+
```
95+
96+
It creates a pipe at `baseai/pipes/summary.ts` in your current directory.
97+
98+
---
99+
100+
## Step #4: Set Environment Variables
101+
102+
Use following command to create a `.env` file in your project directory.
103+
104+
```bash
105+
cp .env.baseai.example .env
106+
```
107+
108+
Set the `OPENAI_API_KEY` in the `.env` file.
109+
110+
## Step #5: Add API Route Handler
111+
112+
Create a new API route handler `app/api/langbase/pipes/run/route.ts` to use the pipe.
113+
114+
<CodeGroup exampleTitle="API Route Handler" title="API Route Handler for Pipe Run">
115+
```ts {{ title: 'app/api/langbase/pipes/run/route.ts' }}
116+
import {Pipe} from '@baseai/core';
117+
import {NextRequest} from 'next/server';
118+
import pipeSummary from '../../../../../baseai/pipes/summary';
119+
120+
export async function POST(req: NextRequest) {
121+
const runOptions = await req.json();
122+
123+
// 1. Initiate the Pipe.
124+
const pipe = new Pipe(pipeSummary());
125+
126+
// 2. Run the pipe
127+
const result = await pipe.run(runOptions);
128+
129+
// 3. Return the response stringified.
130+
return new Response(JSON.stringify(result));
131+
}
132+
133+
```
134+
</CodeGroup>
135+
136+
137+
## Step #6: Add React Component
138+
139+
Add following to your Next.js app to run the pipe.
140+
141+
- Pipe run **page** at `app/pipe-run/page.tsx`
142+
- Pipe run **component** at `components/pipe-run.tsx` — This component will run the pipe.
143+
- UI **Button** component at `components/ui/button.tsx`
144+
- UI **Input** component at `components/ui/input.tsx`
145+
146+
Install the required dependencies.
147+
148+
```bash
149+
npm install @radix-ui/react-slot class-variance-authority clsx tailwind-merge
150+
```
151+
152+
<CodeGroup exampleTitle="React Component" title="React Component for Pipe Run">
153+
```tsx {{ title: 'app/pipe-run/page.tsx' }}
154+
import PipeRunExample from '@/components/pipe-run';
155+
156+
export default function Page() {
157+
return (
158+
<div className="w-full max-w-md">
159+
160+
<h1 className="text-2xl font-light text-gray-800 mb-1 text-center">
161+
⌘ Langbase AI Agent Pipe: Run
162+
</h1>
163+
164+
<p className="text-muted-foreground text-base font-light mb-20 text-center">
165+
Run a pipe to generate a text completion
166+
</p>
167+
168+
<PipeRunExample />
169+
</div>
170+
);
171+
}
172+
```
173+
174+
```tsx {{ title: 'components/pipe-run.tsx' }}
175+
'use client';
176+
177+
import {Button} from '@/components/ui/button';
178+
import {Input} from '@/components/ui/input';
179+
import {useState} from 'react';
180+
181+
export default function PipeRunExample() {
182+
const [prompt, setPrompt] = useState('Who are you?');
183+
const [completion, setCompletion] = useState('');
184+
const [loading, setLoading] = useState(false);
185+
186+
const handleSubmit = async (e: any) => {
187+
e.preventDefault();
188+
if (!prompt.trim()) return;
189+
190+
setLoading(true);
191+
try {
192+
const response = await fetch('/api/langbase/pipes/run', {
193+
method: 'POST',
194+
headers: {'Content-Type': 'application/json'},
195+
// Send prompt as an LLM message.
196+
body: JSON.stringify({
197+
messages: [{role: 'user', content: prompt}],
198+
}),
199+
});
200+
201+
if (!response.ok) {
202+
throw new Error('Network response was not ok');
203+
}
204+
205+
// Parse the JSON response.
206+
const data = await response.json();
207+
setCompletion(data.completion);
208+
} catch (error) {
209+
console.error('Error:', error);
210+
setCompletion('An error occurred while generating the completion.');
211+
} finally {
212+
setLoading(false);
213+
}
214+
};
215+
216+
return (
217+
<div className="bg-neutral-200 rounded-md p-2 flex flex-col gap-2 w-full">
218+
<form
219+
onSubmit={handleSubmit}
220+
className="flex flex-col w-full items-center gap-2"
221+
>
222+
<Input
223+
type="text"
224+
placeholder="Enter prompt message here"
225+
value={prompt}
226+
onChange={e => setPrompt(e.target.value)}
227+
required
228+
/>
229+
230+
<Button type="submit" className="w-full" disabled={loading}>
231+
{loading ? 'AI is thinking...' : 'Ask AI'}
232+
</Button>
233+
</form>
234+
235+
{!loading && completion && (
236+
<p className="mt-4">
237+
<strong>AI:</strong> {completion}
238+
</p>
239+
)}
240+
</div>
241+
);
242+
}
243+
```
244+
245+
```tsx {{ title: 'components/ui/button.tsx' }}
246+
import * as React from 'react';
247+
import {Slot} from '@radix-ui/react-slot';
248+
import {cva, type VariantProps} from 'class-variance-authority';
249+
250+
import {cn} from '@/lib/utils';
251+
252+
const buttonVariants = cva(
253+
'inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',
254+
{
255+
variants: {
256+
variant: {
257+
default: 'bg-primary text-primary-foreground hover:bg-primary/90',
258+
destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',
259+
outline: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',
260+
secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
261+
ghost: 'hover:bg-accent hover:text-accent-foreground',
262+
link: 'text-primary underline-offset-4 hover:underline',
263+
},
264+
size: {
265+
default: 'h-10 px-4 py-2',
266+
sm: 'h-9 rounded-md px-3',
267+
lg: 'h-11 rounded-md px-8',
268+
icon: 'h-10 w-10',
269+
},
270+
},
271+
defaultVariants: {
272+
variant: 'default',
273+
size: 'default',
274+
},
275+
},
276+
);
277+
278+
export interface ButtonProps
279+
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
280+
VariantProps<typeof buttonVariants> {
281+
asChild?: boolean;
282+
}
283+
284+
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
285+
({className, variant, size, asChild = false, ...props}, ref) => {
286+
const Comp = asChild ? Slot : 'button';
287+
return <Comp className={cn(buttonVariants({variant, size, className}))} ref={ref} {...props} />;
288+
},
289+
);
290+
Button.displayName = 'Button';
291+
292+
export {Button, buttonVariants};
293+
```
294+
295+
```tsx {{ title: 'components/ui/input.tsx' }}
296+
import * as React from 'react';
297+
298+
import {cn} from '@/lib/utils';
299+
300+
export interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {}
301+
302+
const Input = React.forwardRef<HTMLInputElement, InputProps>(({className, type, ...props}, ref) => {
303+
return (
304+
<input
305+
type={type}
306+
className={cn(
307+
'flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',
308+
className,
309+
)}
310+
ref={ref}
311+
{...props}
312+
/>
313+
);
314+
});
315+
Input.displayName = 'Input';
316+
317+
export {Input};
318+
```
319+
320+
```tsx {{ title: 'lib/utils.ts' }}
321+
import {type ClassValue, clsx} from 'clsx';
322+
import {twMerge} from 'tailwind-merge';
323+
324+
export function cn(...inputs: ClassValue[]) {
325+
return twMerge(clsx(inputs));
326+
}
327+
```
328+
329+
</CodeGroup>
330+
331+
Refer to [Next.js with BaseAI](https://github.com/LangbaseInc/baseai/tree/main/examples/nextjs) codebase for more details.
332+
333+
334+
---
335+
336+
## Step #7: Run the Next.js BaseAI App
337+
338+
Run BaseAI dev server and start the Next.js app.
339+
340+
```bash
341+
npx baseai@latest dev # Start BaseAI dev server
342+
npm run dev # Start Next.js app
343+
```
344+
345+
Open [http://localhost:3000/pipe-run](http://localhost:3000/pipe-run) to see the pipe run page.
346+
347+
Write a prompt message and click on the `Ask AI` button to generate the completion. The AI response will be displayed below the button. This all happens locally on your machine.
348+
349+
---
350+
351+
## Step #8: Deploy BaseAI project on Langbase
352+
353+
To deploy the project on Langbase, you need to authenticate with your Langbase account.
354+
355+
```bash
356+
npx baseai@latest auth
357+
```
358+
359+
After authentication, you can deploy the project using the following command.
360+
361+
```bash
362+
npx baseai@latest deploy
363+
```
364+
365+
This will deploy your project on Langbase and you can access it as a highly scalable API. Check the [BaseAI `deploy` documentation](https://baseai.dev/docs/deployment/deploy) for more details.
366+
367+
---
368+
369+
## Step #9: Deploy Next.js app
370+
371+
Deploy your Next.js app using Vercel or any other hosting provider and set the following environment variables.
372+
373+
```bash
374+
OPENAI_API_KEY="" #your_openai_api_key
375+
LANGBASE_API_KEY="" #your_langbase_api_key
376+
```
377+
378+
Langbase API key is the user or org API key that you authenticated with. You can obtain your [User/Org API Key](https://langbase.com/docs/api-reference/api-keys) from the Langbase dashboard.
379+
380+
---

0 commit comments

Comments
 (0)