Framework Integration Guides

Step-by-step guides for integrating the RAG Chats widget with popular frontend frameworks.

React

Initialize the widget in a useEffect hook to ensure it runs after the component mounts:

500">import { useEffect } 500">from 500">class="text-green-500">'react';
500">import RagChatsWidget 500">from 500">class="text-green-500">'@rag-chats/widget';

500">function App() {
  useEffect(() => {
    RagChatsWidget.init({
      botId: 500">class="text-green-500">'YOUR_BOT_ID',
      apiKey: 500">class="text-green-500">'YOUR_API_KEY',
      theme: {
        primaryColor: 500">class="text-green-500">'#6366f1',
      }
    });

    500">class=500">class="text-green-500">"text-muted-foreground">// Cleanup on unmount
    500">return () => {
      RagChatsWidget.destroy();
    };
  }, []);

  500">return (
    <div>
      <h1>My App</h1>
      {/* Widget appears automatically */}
    </div>
  );
}

500">export default App;

Custom Hook

Create a reusable hook for cleaner code:

500">class=500">class="text-green-500">"text-muted-foreground">// hooks/useRagChatsWidget.ts
500">import { useEffect } 500">from 500">class="text-green-500">'react';
500">import RagChatsWidget, { WidgetConfig } 500">from 500">class="text-green-500">'@rag-chats/widget';

500">export 500">function useRagChatsWidget(config: WidgetConfig) {
  useEffect(() => {
    RagChatsWidget.init(config);
    500">return () => RagChatsWidget.destroy();
  }, []);
}

500">class=500">class="text-green-500">"text-muted-foreground">// Usage in component
500">function App() {
  useRagChatsWidget({
    botId: 500">class="text-green-500">'YOUR_BOT_ID',
    apiKey: 500">class="text-green-500">'YOUR_API_KEY',
  });
  
  500">return <div>My App</div>;
}

Next.js

For Next.js, use 'use client' directive and handle the widget in a client component:

500">class=500">class="text-green-500">"text-muted-foreground">// components/ChatWidget.tsx
500">class="text-green-500">'use client';

500">import { useEffect } 500">from 500">class="text-green-500">'react';
500">import RagChatsWidget 500">from 500">class="text-green-500">'@rag-chats/widget';

500">export 500">function ChatWidget() {
  useEffect(() => {
    RagChatsWidget.init({
      botId: process.env.NEXT_PUBLIC_BOT_ID!,
      apiKey: process.env.NEXT_PUBLIC_WIDGET_API_KEY!,
    });

    500">return () => RagChatsWidget.destroy();
  }, []);

  500">return 500">null;
}

500">class=500">class="text-green-500">"text-muted-foreground">// app/layout.tsx
500">import { ChatWidget } 500">from 500">class="text-green-500">'@/components/ChatWidget';

500">export default 500">function RootLayout({ children }) {
  500">return (
    <html>
      <body>
        {children}
        <ChatWidget />
      </body>
    </html>
  );
}

Environment Variables

Use NEXT_PUBLIC_ prefix for client-side environment variables in Next.js. Never expose secret API keys in client code.

Vue 3

Use onMounted and onUnmounted lifecycle hooks:

<script setup>
500">import { onMounted, onUnmounted } 500">from 500">class="text-green-500">'vue';
500">import RagChatsWidget 500">from 500">class="text-green-500">'@rag-chats/widget';

onMounted(() => {
  RagChatsWidget.init({
    botId: 500">class="text-green-500">'YOUR_BOT_ID',
    apiKey: 500">class="text-green-500">'YOUR_API_KEY',
    theme: {
      primaryColor: 500">class="text-green-500">'#6366f1',
    }
  });
});

onUnmounted(() => {
  RagChatsWidget.destroy();
});
</script>

<template>
  <div>
    <h1>My Vue App</h1>
  </div>
</template>

Vue Composable

500">class=500">class="text-green-500">"text-muted-foreground">// composables/useRagChatsWidget.ts
500">import { onMounted, onUnmounted } 500">from 500">class="text-green-500">'vue';
500">import RagChatsWidget, { WidgetConfig } 500">from 500">class="text-green-500">'@rag-chats/widget';

500">export 500">function useRagChatsWidget(config: WidgetConfig) {
  onMounted(() => {
    RagChatsWidget.init(config);
  });

  onUnmounted(() => {
    RagChatsWidget.destroy();
  });

  500">return {
    open: () => RagChatsWidget.open(),
    close: () => RagChatsWidget.close(),
    isOpen: () => RagChatsWidget.isOpen(),
  };
}

500">class=500">class="text-green-500">"text-muted-foreground">// Usage in component
<script setup>
500">import { useRagChatsWidget } 500">from 500">class="text-green-500">'@/composables/useRagChatsWidget';

500">const { open, close } = useRagChatsWidget({
  botId: 500">class="text-green-500">'YOUR_BOT_ID',
  apiKey: 500">class="text-green-500">'YOUR_API_KEY',
});
</script>

Angular

Initialize in ngOnInit and cleanup in ngOnDestroy:

500">class=500">class="text-green-500">"text-muted-foreground">// app.component.ts
500">import { Component, OnInit, OnDestroy } 500">from 500">class="text-green-500">'@angular/core';
500">import RagChatsWidget 500">from 500">class="text-green-500">'@rag-chats/widget';

@Component({
  selector: 500">class="text-green-500">'app-root',
  template: 500">class="text-green-500">'<router-outlet></router-outlet>'
})
500">export 500">class AppComponent 500">implements OnInit, OnDestroy {
  ngOnInit() {
    RagChatsWidget.init({
      botId: 500">class="text-green-500">'YOUR_BOT_ID',
      apiKey: 500">class="text-green-500">'YOUR_API_KEY',
      theme: {
        primaryColor: 500">class="text-green-500">'#6366f1',
      }
    });
  }

  ngOnDestroy() {
    RagChatsWidget.destroy();
  }
}

Angular Service

500">class=500">class="text-green-500">"text-muted-foreground">// services/rag-chats.service.ts
500">import { Injectable, OnDestroy } 500">from 500">class="text-green-500">'@angular/core';
500">import RagChatsWidget, { WidgetConfig } 500">from 500">class="text-green-500">'@rag-chats/widget';

@Injectable({
  providedIn: 500">class="text-green-500">'root'
})
500">export 500">class RagChatsService 500">implements OnDestroy {
  private initialized = 500">false;

  init(config: WidgetConfig) {
    500">if (!500">this.initialized) {
      RagChatsWidget.init(config);
      500">this.initialized = 500">true;
    }
  }

  open() { RagChatsWidget.open(); }
  close() { RagChatsWidget.close(); }
  isOpen() { 500">return RagChatsWidget.isOpen(); }

  ngOnDestroy() {
    RagChatsWidget.destroy();
    500">this.initialized = 500">false;
  }
}

500">class=500">class="text-green-500">"text-muted-foreground">// app.component.ts
constructor(private ragChats: RagChatsService) {}

ngOnInit() {
  500">this.ragChats.init({
    botId: 500">class="text-green-500">'YOUR_BOT_ID',
    apiKey: 500">class="text-green-500">'YOUR_API_KEY',
  });
}

Svelte

<script>
  500">import { onMount, onDestroy } 500">from 500">class="text-green-500">'svelte';
  500">import RagChatsWidget 500">from 500">class="text-green-500">'@rag-chats/widget';

  onMount(() => {
    RagChatsWidget.init({
      botId: 500">class="text-green-500">'YOUR_BOT_ID',
      apiKey: 500">class="text-green-500">'YOUR_API_KEY',
    });
  });

  onDestroy(() => {
    RagChatsWidget.destroy();
  });
</script>

<main>
  <h1>My Svelte App</h1>
</main>

Script Tag in SPA

If you prefer the script tag method in a single-page app, load it dynamically:

500">class=500">class="text-green-500">"text-muted-foreground">// Load widget script dynamically
500">function loadWidget() {
  500">const script = document.createElement(500">class="text-green-500">'script');
  script.src = 500">class="text-green-500">'https:500">class="text-muted-foreground500">class="text-green-500">">//widget.ragchats.ai/embed.js';
  script.setAttribute(500">class="text-green-500">'data-bot-id', 500">class="text-green-500">'YOUR_BOT_ID');
  script.setAttribute(500">class="text-green-500">'data-api-key', 500">class="text-green-500">'YOUR_API_KEY');
  script.500">async = 500">true;
  document.body.appendChild(script);
}

500">class=500">class="text-green-500">"text-muted-foreground">// Call when app initializes
loadWidget();

Common Patterns

Conditional Loading

Only load the widget for certain users or pages:

500">class=500">class="text-green-500">"text-muted-foreground">// Only show 500">for logged-in users
500">if (user.isLoggedIn) {
  RagChatsWidget.init({
    botId: 500">class="text-green-500">'YOUR_BOT_ID',
    apiKey: 500">class="text-green-500">'YOUR_API_KEY',
  });
}

500">class=500">class="text-green-500">"text-muted-foreground">// Only show on support pages
500">if (window.location.pathname.startsWith(500">class="text-green-500">'/support')) {
  RagChatsWidget.init({...});
}

User Context

Pass user information to personalize responses:

RagChatsWidget.init({
  botId: 500">class="text-green-500">'YOUR_BOT_ID',
  apiKey: 500">class="text-green-500">'YOUR_API_KEY',
  500">class=500">class="text-green-500">"text-muted-foreground">// User context passed to bot
  context: {
    userId: user.id,
    email: user.email,
    plan: user.subscription,
  }
});