# How to add an AI chatbot to Next.js and React

URL: https://instantknowledgebot.com/guides/add-chatbot-to-react-nextjs  
Last updated: 2026-10-14

> To add an AI chatbot to a Next.js app, load the bot's widget script with the next/script component in app/layout.tsx (App Router) or pages/_app.tsx (Pages Router), using strategy lazyOnload. In a plain React app, append the script once from a useEffect in your root component; the bot answers from your own documents.

To **add an AI chatbot to Next.js** or any React app, you load one script, the same widget used on every InstantKnowledgeBot site, from your root layout. It takes about three minutes. The chatbot answers your users from your own documentation, which makes it a quick way to add in-app help to a SaaS product, dashboard or docs site.

## What do you need before you start?

- A **Next.js** app (App Router or Pages Router) or a **React** app (Vite, Create React App or similar).
- A **bot** created from your documents. [Sign up free](/signup), click **New bot**, choose a template (the **SaaS help desk** template formats answers as numbered steps with code blocks) and upload your docs.
- Your **bot ID**, shown in the bot's **Embed & share** tab.

## How do you add the chatbot to the Next.js App Router?

Add the `Script` component to `app/layout.tsx`, inside `<body>`:

```tsx
// app/layout.tsx
import Script from 'next/script';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        {children}
        <Script
          src="https://instantknowledgebot.com/widget.js"
          data-bot="YOUR_BOT_ID"
          strategy="lazyOnload"
        />
      </body>
    </html>
  );
}
```

`strategy="lazyOnload"` loads the widget after the page has finished loading, so it never competes with your app's own resources. Because the root layout persists across navigations, the script loads once and the bubble stays put as users move around.

## How do you add it with the Pages Router?

Add the same `Script` to `pages/_app.tsx`:

```tsx
// pages/_app.tsx
import type { AppProps } from 'next/app';
import Script from 'next/script';

export default function App({ Component, pageProps }: AppProps) {
  return (
    <>
      <Component {...pageProps} />
      <Script
        src="https://instantknowledgebot.com/widget.js"
        data-bot="YOUR_BOT_ID"
        strategy="lazyOnload"
      />
    </>
  );
}
```

## How do you add it to a plain React app?

Load the script once from a `useEffect` in your root component:

```tsx
// App.tsx
import { useEffect } from 'react';

export default function App() {
  useEffect(() => {
    if (document.querySelector('script[data-bot]')) return; // already loaded
    const s = document.createElement('script');
    s.src = 'https://instantknowledgebot.com/widget.js';
    s.dataset.bot = 'YOUR_BOT_ID';
    s.defer = true;
    document.body.appendChild(s);
  }, []);

  return <YourRoutes />;
}
```

The guard line stops a second copy loading in development, where React's Strict Mode runs effects twice. Alternatively, paste the plain `<script>` tag into `index.html` just before `</body>`, as in the [HTML guide](/guides/add-chatbot-to-html-website).

## How do you configure the widget?

Use data attributes on the script, or set the same options in the bot's **Settings** tab:

| Attribute | Value | Effect |
|---|---|---|
| `data-bot` | your bot ID | Required. Which bot to load. |
| `data-position` | `left` or `right` | Corner for the bubble. |
| `data-open` | `true` | Opens the chat on load. Good for a dedicated help route. |
| `data-color` | `#RRGGBB` | Accent color override. |

To keep the bot ID in configuration, use a public environment variable, for example `data-bot={process.env.NEXT_PUBLIC_IKB_BOT_ID}`. The ID isn't a secret: anyone can see it in the page source.

## How do you embed the chat inside a React page?

For a help route where the chat is the main content, render the inline iframe:

```tsx
export function HelpChat() {
  return (
    <iframe
      src="https://instantknowledgebot.com/embed/YOUR_BOT_ID"
      title="Help assistant"
      width="100%"
      height={640}
      style={{ border: 0, borderRadius: 16, maxWidth: 720 }}
      allow="clipboard-write"
    />
  );
}
```

See [iframe and share link embedding](/guides/embed-chatbot-iframe-share-link) for more.

## What about Content Security Policy?

If your app sends a CSP header, allow:

- `script-src https://instantknowledgebot.com`
- `frame-src https://instantknowledgebot.com`
- `connect-src https://instantknowledgebot.com`

Then check the browser console for any blocked requests after deploying.

## How do you test it?

1. Run your app locally and open it. The bubble appears in the corner.
2. Ask a question your docs answer, and one they don't.
3. Deploy, then check the bot's overview in the dashboard. It shows where the bot is installed and the conversations.

Local and preview deployments use real messages from your allowance, so keep testing proportionate, or [connect your own AI key](/guides/bring-your-own-ai-key) for development.

## Should the chatbot be on every route?

Not necessarily. In a web app, think about where questions come up:

- **Marketing pages and pricing:** visitors ask about features, plans and limits. A bubble on every public route helps.
- **Onboarding and settings screens:** new users get stuck here most. A bubble, or `data-open="true"` on a dedicated help route, is useful.
- **Checkout or payment flows:** some teams prefer no distractions here. Load the script only in the layouts where you want it.

In the App Router, you can scope the script by placing it in a nested layout (for example `app/(marketing)/layout.tsx`) instead of the root layout. Navigating between routes that share that layout keeps the bubble; routes outside it won't load the script. Note that once the widget script has loaded in a browser tab, client-side navigation to another layout won't unload it automatically, so test the behaviour you want.

## How do you keep answers in sync with your docs?

Treat the bot's knowledge like your docs site: when you ship a release that changes how something works, update the matching document in the bot's **Knowledge** tab the same day. There's no automatic sync, so add it to your release checklist. Remove documents for retired features, too, or the bot may keep describing them.

## What should you do next?

Write a fallback message pointing to your support email, add up to six starter questions, and review **knowledge gaps** after each release: they show exactly which parts of your docs users can't find answers in. The [SaaS support chatbot](/solutions/saas-customer-support-chatbot) page has a fuller playbook, and plan limits are on the [pricing page](/pricing).

## Frequently asked questions

**Is there an npm package for the chatbot?**

No package is needed. The widget is a single script that you load with next/script or a small useEffect, as shown in this guide.

**Will the widget load twice when routes change?**

Not if you load it in the root layout (Next.js) or the root component (React). The layout persists across client-side navigations, so the script loads once.

**Does it work with server components?**

Yes. Put the Script component in the root layout, which can stay a server component; next/script handles loading on the client.

**Can I pass the bot ID from an environment variable?**

Yes. Use a public variable such as NEXT_PUBLIC_IKB_BOT_ID and reference it in data-bot. The bot ID isn't secret; it appears in your page source either way.

**Do I need to configure a Content Security Policy?**

If your app sets one, allow scripts and frames from https://instantknowledgebot.com, plus connections to it.
