Back to Blog
DevelopmentDec 20, 20255 min read

How to Add a Chatbot to Your React Website: Complete Integration Guide

BB

Binary Buddies

Author

Step-by-step guide to integrating an AI chatbot into your React application. Learn multiple integration methods, best practices, and troubleshooting tips for seamless chatbot deployment.

How to Add a Chatbot to Your React Website: Complete Integration Guide

React is one of the most popular frameworks for building modern web applications. If you're using React and want to add an AI chatbot to enhance user experience, this guide will walk you through the entire process step by step.

Why Add a Chatbot to Your React App?

Before we dive into the implementation, here's why chatbots are valuable for React applications:

  • Enhanced User Experience: Provide instant help without leaving the page
  • Reduced Bounce Rate: Engage visitors and keep them on your site longer
  • 24/7 Support: Answer questions even when your team is offline
  • Lead Capture: Collect user information and qualify leads automatically
  • Modern UX: Chatbots are expected in modern web applications

Prerequisites

To follow this guide, you should have:

  • A React application (created with Create React App, Next.js, or similar)
  • Basic knowledge of React components
  • A chatbot account with API credentials
  • Node.js and npm/yarn installed

Method 1: Simple Script Tag Integration (Recommended for Beginners)

This is the easiest method and works with any React setup.

Step 1: Create a Chatbot Component

Create a new file ChatbotWidget.js in your src/components folder:

import { useEffect } from 'react';

const ChatbotWidget = ({ chatbotId, apiKey, theme = 'classic', position = 'bottom-right' }) => {
  useEffect(() => {
    // Create script element
    const script = document.createElement('script');
    script.src = 'https://your-domain.com/widget.js';
    script.setAttribute('data-chatbot-id', chatbotId);
    script.setAttribute('data-api-key', apiKey);
    script.setAttribute('data-theme', theme);
    script.setAttribute('data-position', position);
    script.async = true;

    // Append to body
    document.body.appendChild(script);

    // Cleanup function
    return () => {
      // Remove script when component unmounts
      const existingScript = document.querySelector(`script[data-chatbot-id="${chatbotId}"]`);
      if (existingScript) {
        existingScript.remove();
      }
      // Remove widget container
      const widgetContainer = document.getElementById('chatbot-widget-container');
      if (widgetContainer) {
        widgetContainer.remove();
      }
    };
  }, [chatbotId, apiKey, theme, position]);

  return null; // This component doesn't render anything
};

export default ChatbotWidget;

Step 2: Use the Component in Your App

In your main App.js or layout component:

import React from 'react';
import ChatbotWidget from './components/ChatbotWidget';
import './App.css';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <h1>My React App</h1>
      </header>
      
      {/* Add Chatbot Widget */}
      <ChatbotWidget
        chatbotId="YOUR_CHATBOT_ID"
        apiKey="YOUR_API_KEY"
        theme="classic"
        position="bottom-right"
      />
    </div>
  );
}

export default App;

Step 3: Store Credentials Securely

For production, store your credentials in environment variables:

Create .env file:

REACT_APP_CHATBOT_ID=your_chatbot_id
REACT_APP_CHATBOT_API_KEY=your_api_key

Update your component:

<ChatbotWidget
  chatbotId={process.env.REACT_APP_CHATBOT_ID}
  apiKey={process.env.REACT_APP_CHATBOT_API_KEY}
  theme="classic"
  position="bottom-right"
/>

Important: Add .env to your .gitignore file to keep credentials secure!

Method 2: Next.js Integration

If you're using Next.js, here's the best approach:

Step 1: Create a Chatbot Component

Create components/ChatbotWidget.js:

import { useEffect } from 'react';

export default function ChatbotWidget({ chatbotId, apiKey, theme = 'classic', position = 'bottom-right' }) {
  useEffect(() => {
    // Only load on client side
    if (typeof window === 'undefined') return;

    const script = document.createElement('script');
    script.src = process.env.NEXT_PUBLIC_CHATBOT_WIDGET_URL || 'https://your-domain.com/widget.js';
    script.setAttribute('data-chatbot-id', chatbotId);
    script.setAttribute('data-api-key', apiKey);
    script.setAttribute('data-theme', theme);
    script.setAttribute('data-position', position);
    script.async = true;

    document.body.appendChild(script);

    return () => {
      const existingScript = document.querySelector(`script[data-chatbot-id="${chatbotId}"]`);
      if (existingScript) {
        existingScript.remove();
      }
      const widgetContainer = document.getElementById('chatbot-widget-container');
      if (widgetContainer) {
        widgetContainer.remove();
      }
    };
  }, [chatbotId, apiKey, theme, position]);

  return null;
}

Step 2: Add to Your Layout

In app/layout.js (App Router) or pages/_app.js (Pages Router):

For App Router (app/layout.js):

import ChatbotWidget from '@/components/ChatbotWidget';

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        {children}
        <ChatbotWidget
          chatbotId={process.env.NEXT_PUBLIC_CHATBOT_ID}
          apiKey={process.env.NEXT_PUBLIC_CHATBOT_API_KEY}
          theme="classic"
          position="bottom-right"
        />
      </body>
    </html>
  );
}

For Pages Router (pages/_app.js):

import ChatbotWidget from '../components/ChatbotWidget';
import '../styles/globals.css';

function MyApp({ Component, pageProps }) {
  return (
    <>
      <Component {...pageProps} />
      <ChatbotWidget
        chatbotId={process.env.NEXT_PUBLIC_CHATBOT_ID}
        apiKey={process.env.NEXT_PUBLIC_CHATBOT_API_KEY}
        theme="classic"
        position="bottom-right"
      />
    </>
  );
}

export default MyApp;

Step 3: Configure Environment Variables

Create .env.local:

NEXT_PUBLIC_CHATBOT_ID=your_chatbot_id
NEXT_PUBLIC_CHATBOT_API_KEY=your_api_key
NEXT_PUBLIC_CHATBOT_WIDGET_URL=https://your-domain.com/widget.js

Method 3: Custom React Hook

For more control and reusability, create a custom hook:

Create hooks/useChatbot.js:

import { useEffect, useRef } from 'react';

export const useChatbot = (config) => {
  const scriptLoaded = useRef(false);

  useEffect(() => {
    if (scriptLoaded.current) return;

    const {
      chatbotId,
      apiKey,
      theme = 'classic',
      position = 'bottom-right',
      widgetUrl = 'https://your-domain.com/widget.js',
    } = config;

    if (!chatbotId || !apiKey) {
      console.warn('Chatbot ID and API Key are required');
      return;
    }

    const script = document.createElement('script');
    script.src = widgetUrl;
    script.setAttribute('data-chatbot-id', chatbotId);
    script.setAttribute('data-api-key', apiKey);
    script.setAttribute('data-theme', theme);
    script.setAttribute('data-position', position);
    script.async = true;

    script.onload = () => {
      scriptLoaded.current = true;
      console.log('Chatbot widget loaded successfully');
    };

    script.onerror = () => {
      console.error('Failed to load chatbot widget');
    };

    document.body.appendChild(script);

    return () => {
      const existingScript = document.querySelector(`script[data-chatbot-id="${chatbotId}"]`);
      if (existingScript) {
        existingScript.remove();
        scriptLoaded.current = false;
      }
      const widgetContainer = document.getElementById('chatbot-widget-container');
      if (widgetContainer) {
        widgetContainer.remove();
      }
    };
  }, [config]);
};

Use the Hook in Your Component:

import React from 'react';
import { useChatbot } from './hooks/useChatbot';

function App() {
  useChatbot({
    chatbotId: process.env.REACT_APP_CHATBOT_ID,
    apiKey: process.env.REACT_APP_CHATBOT_API_KEY,
    theme: 'classic',
    position: 'bottom-right',
  });

  return (
    <div className="App">
      <h1>My React App with Chatbot</h1>
    </div>
  );
}

export default App;

Method 4: Conditional Loading

Load the chatbot only when needed (e.g., after user interaction):

import { useState, useEffect } from 'react';

function App() {
  const [loadChatbot, setLoadChatbot] = useState(false);

  useEffect(() => {
    if (!loadChatbot) return;

    const script = document.createElement('script');
    script.src = 'https://your-domain.com/widget.js';
    script.setAttribute('data-chatbot-id', process.env.REACT_APP_CHATBOT_ID);
    script.setAttribute('data-api-key', process.env.REACT_APP_CHATBOT_API_KEY);
    script.async = true;
    document.body.appendChild(script);

    return () => {
      const script = document.querySelector('script[data-chatbot-id]');
      if (script) script.remove();
    };
  }, [loadChatbot]);

  return (
    <div>
      <button onClick={() => setLoadChatbot(true)}>
        Enable Chat Support
      </button>
    </div>
  );
}

Advanced: TypeScript Support

If you're using TypeScript, create a typed component:

import { useEffect } from 'react';

interface ChatbotWidgetProps {
  chatbotId: string;
  apiKey: string;
  theme?: 'classic' | 'vibrant' | 'minimal' | 'ocean' | 'sunset' | 'forest' | 'midnight' | 'coral' | 'amber' | 'neon';
  position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
  widgetUrl?: string;
}

const ChatbotWidget: React.FC<ChatbotWidgetProps> = ({
  chatbotId,
  apiKey,
  theme = 'classic',
  position = 'bottom-right',
  widgetUrl = 'https://your-domain.com/widget.js',
}) => {
  useEffect(() => {
    const script = document.createElement('script');
    script.src = widgetUrl;
    script.setAttribute('data-chatbot-id', chatbotId);
    script.setAttribute('data-api-key', apiKey);
    script.setAttribute('data-theme', theme);
    script.setAttribute('data-position', position);
    script.async = true;

    document.body.appendChild(script);

    return () => {
      const existingScript = document.querySelector(`script[data-chatbot-id="${chatbotId}"]`);
      if (existingScript) {
        existingScript.remove();
      }
      const widgetContainer = document.getElementById('chatbot-widget-container');
      if (widgetContainer) {
        widgetContainer.remove();
      }
    };
  }, [chatbotId, apiKey, theme, position, widgetUrl]);

  return null;
};

export default ChatbotWidget;

Testing Your Integration

  1. Start your React app: npm start or yarn start
  2. Open in browser: Navigate to http://localhost:3000
  3. Check for the chatbot button: Look in the corner you specified
  4. Test the chat: Click the button and send a test message
  5. Check console: Open browser DevTools (F12) and verify no errors

Troubleshooting Common Issues

Issue: Chatbot Not Appearing

Solutions:

  • Verify script URL is correct
  • Check that credentials are properly set
  • Ensure component is mounted (check React DevTools)
  • Clear browser cache and reload

Issue: Multiple Chatbot Instances

Solution: Make sure you're only rendering the component once. Check your component tree to ensure it's not duplicated.

Issue: Script Loading Errors

Solutions:

  • Check network tab in DevTools for failed requests
  • Verify CORS settings if using custom domain
  • Ensure widget.js URL is accessible

Issue: TypeScript Errors

Solution: Install type definitions or create your own as shown in the TypeScript example above.

Best Practices

  1. Environment Variables: Never hardcode API keys. Always use environment variables.
  2. Cleanup: Always clean up the script in the useEffect cleanup function.
  3. Error Handling: Add error handling for script loading failures.
  4. Performance: Consider lazy loading the chatbot for better initial page load.
  5. Testing: Test on multiple browsers and devices.
  6. Security: Use domain restrictions in your chatbot settings.

Performance Optimization

Lazy Load the Chatbot

import { lazy, Suspense } from 'react';

const ChatbotWidget = lazy(() => import('./components/ChatbotWidget'));

function App() {
  return (
    <div>
      {/* Your app content */}
      <Suspense fallback={null}>
        <ChatbotWidget
          chatbotId={process.env.REACT_APP_CHATBOT_ID}
          apiKey={process.env.REACT_APP_CHATBOT_API_KEY}
        />
      </Suspense>
    </div>
  );
}

Next Steps

After integrating your chatbot:

  1. Customize the theme to match your brand
  2. Add knowledge base documents for better responses
  3. Monitor conversations to improve the chatbot
  4. A/B test different themes and positions
  5. Analyze metrics to measure engagement

Conclusion

Adding a chatbot to your React application is straightforward. Choose the method that best fits your project structure:

  • Simple projects: Use Method 1 (Simple Script Tag)
  • Next.js apps: Use Method 2 (Next.js Integration)
  • Complex apps: Use Method 3 (Custom Hook)
  • Conditional loading: Use Method 4

Remember to keep your API keys secure, test thoroughly, and monitor performance. Your React app will now have a powerful AI assistant ready to help your users 24/7!

Share this article

Related Articles