guide · next.js app router

Add Bubblio to a Next.js app

Two small files and one edit. When you're done, a live support bubble sits in the corner of every page of your site. No expertise needed — each step below tells you exactly which file to open and highlights the lines you addin green.

where things go

your-app/
.env.localedityour API key (step 1)
app/
layout.tsxeditthe bubble, on every page (step 3)
page.tsx
api/bubblio/session/route.tsnew filemints sessions (step 2)
api/bubblio/tools/route.tsnew fileoptional — answers questions with your data (step 4)
00

Install the packages

In your project folder, run:

terminal
npm install @bubblio/server @bubblio/widget
01

Put your API key in .env.local

Grab a key from your Bubblio dashboard → API Keys (it starts with bbl_). Open the file called .env.local in the root of your project — create it if it doesn't exist — and add one line:

.env.local
BUBBLIO_API_KEY=bbl_your_key_here

This file stays on your computer and your server — it's never sent to visitors' browsers. That's the whole reason for step 2: the browser asks your server for a session, and only your server knows the key.

02

Create the session route (new file)

Create a new file at app/api/bubblio/session/route.ts (make the folders if they don't exist). Paste this — the entire file:

app/api/bubblio/session/route.tsnew file
import { createBubblioSession } from '@bubblio/server'export async function POST() {const session = await createBubblioSession({bubblioApiKey: process.env.BUBBLIO_API_KEY!,personality: 'You are Aria, a friendly support agent for Acme. Keep answers short.'})return Response.json(session)}

When a visitor opens the bubble, the widget calls this route, and this route asks Bubblio to start a live session on your account. Change the personality text to whoever your assistant should be.

03

Add the bubble to layout.tsx (two lines)

app/layout.tsx is the frame around every page of your site — anything you put there shows up everywhere. That makes it the right home for the bubble. Open it and add the two green lines; everything else is what a typical layout already looks like:

app/layout.tsx2 lines added
import { BubblioWidget } from '@bubblio/widget'import './globals.css'export default function RootLayout({ children }) {return (<html lang="en">  <body>    {children}    <BubblioWidget config={{ serverUrl: '/api/bubblio/session' }} />  </body></html>)}

Only want it on one page instead of everywhere? Put those same two lines in that page's page.tsx instead.

That's it. Run npm run dev, open your site, and the bubble is in the bottom corner of every page — click it and say hello.
04

Optional: answer with your data (tools)

Right now the assistant can talk, but it can't look anything up. Tools fix that: you declare a function name in the session route, and Bubblio calls your server whenever the assistant needs it — signed, so you know it's really Bubblio. Two changes:

app/api/bubblio/session/route.tsadd tools
const session = await createBubblioSession({bubblioApiKey: process.env.BUBBLIO_API_KEY!,personality: 'You are Aria…',tools: [{name: 'get_order_status',description: 'Look up an order by its id',callbackUrl: 'https://your-site.com/api/bubblio/tools',}],})
app/api/bubblio/tools/route.tsnew file
import { createBubblioToolRoute } from '@bubblio/server'export const POST = createBubblioToolRoute({bubblioApiKey: process.env.BUBBLIO_API_KEY!,tools: {get_order_status: async ({ id }) => {  // look it up in YOUR database, return any JSON  return { status: 'shipped' }},},})

Signature verification happens automatically — createBubblioToolRoute fetches your account's signing secret using the API key you already have. There is no second secret to copy. Every call the assistant makes shows up in your dashboard as it happens.

No Next.js? The one-tag script guide →Full SDK reference on npm ↗