@theceloreis/chat-widget
v2.3.0
Published
A customizable React chat widget powered by Google's Generative AI. Easily integrate a support chat interface into your React application.
Readme
@theceloreis/chat-widget
A customizable React chat widget powered by Google's Generative AI. Easily integrate a support chat interface into your React application.
Preview it here: Chat Widget Demo
Features
- Seamless integration with React applications.
- Powered by Google's Generative AI for intelligent responses.
- Customizable appearance, initial messages, and header.
- Encapsulated styles using Shadow DOM to prevent conflicts with your application's styling.
Installation
Prerequisites: This widget requires react and react-dom version 19 or higher as peer dependencies. Ensure your project meets this requirement.
You can install the widget using npm or yarn:
npm install @theceloreis/chat-widget
# or
yarn add @theceloreis/chat-widgetUsage
Import the initChatWidget function and provide your Google Generative AI API key. Styles are encapsulated within the component, so no separate CSS import is typically needed.
You shouldn't worry about the styles, as they are encapsulated within the component using Shadow DOM. This means the widget's styles won't conflict with your application's styles.
initChatWidget({
genAIAPIKey: "YOUR_GOOGLE_GENERATIVE_AI_API_KEY",
});If you want to remove the widget from the page, you can call the destroyChatWidget function:
import { destroyChatWidget } from "@theceloreis/chat-widget";
destroyChatWidget();Important: Replace "YOUR_GOOGLE_GENERATIVE_AI_API_KEY" with your actual Google Generative AI API key.
Local Development
To run this project locally for development or contributions:
Clone the repository:
git clone https://github.com/theceloreis/chat-widget.git cd chat-widgetInstall dependencies:
npm installRun the development server: The
devscript will build the widget in watch mode.npm run devThis command continuously watches for changes in the
srcdirectory and rebuilds the widget.Link for local development (optional but recommended for testing in another project): If you want to test your local changes of
@theceloreis/chat-widgetin another local project that uses it:
- In the
chat-widgetdirectory, run:npm link - In your other project's directory (e.g.,
my-app), run:
This will create a symbolic link, so your other project uses your localnpm link @theceloreis/chat-widgetchat-widgetbuild. Remember to runnpm run dev(ornpm run build) in thechat-widgetdirectory to reflect changes.
Build the widget for production: To create a production-ready you need access to the npm registry. If you have access, run:
make releaseThis will run linting, tests, and build the widget for production. The output will be in the
distdirectory. It will also prompt in the cli which version you are creating (patch, minor or major), after selecting it will trigger the npm release process, publishing the package to the npm registry.
Customization
You can customize the Widget component by passing the following options:
| Option | Type | Description | Default Value |
| -------------- | ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| genAIAPIKey | string | Required. Your Google Generative AI API Key. | - |
| firstMessage | string (optional) | The initial message displayed by the bot when the chat opens. | "Hello! How can I assist you today?" |
| header | object (optional) | An object to customize the chat window's header. | |
| | { title: string; description: string; } | title: The main title in the header. description: A subtitle or description below the title. | { title: "Support Chat", description: "Your personal assistant for all questions" } |
| theme | object (optional) | An object to customize the theme. | |
| | { primaryColor?: string; } | primaryColor: The primary color accent for the widget (e.g., buttons, highlights). Accepts any valid CSS color value. | { primaryColor: "oklch(0.461 0.197 299.95)" } |
Example with Customization
<script src="./dist/chat-widget.umd.js"></script>
<script>
ChatWidget.initChatWidget({
// Your Google Generative AI API Key (required)
genAIAPIKey: "YOUR_GEN_AI_API_KEY",
// The initial message displayed by the bot when the chat opens (optional)
// Default: "Hello! How can I assist you today?"
firstMessage: "Hi there! How can I help you with our services today?",
// Configuration for the chat window's header (optional)
theme: {
// The primary color accent for the widget (e.g., buttons, highlights)
// Accepts any valid CSS color value.
// Default: "oklch(0.461 0.197 299.95)"
primaryColor: "#1d6681",
},
// Configuration for the chat window's header (optional)
header: {
// The main title in the header
// Default: "Support Chat"
title: "Celo Reis (AI agent)",
// A subtitle or description displayed below the title in the header
// Default: "Your personal assistant for all questions"
description: "Ask me anything!",
},
});
</script>
export default MyApp;Architecture choices
Shadow DOM
The widget uses Shadow DOM to encapsulate its styles, ensuring that the widget's appearance does not conflict with the host application's styles. This allows for a clean and isolated styling environment, making it easier to integrate the widget into various applications without worrying about CSS conflicts.
I also thought about using an iframe, but it would have added complexity in terms of communication between the widget and the host application. Shadow DOM provides a simpler and more efficient way to achieve style encapsulation while still allowing for easy interaction with the host application. This would allow better future integration between the widget and the host application.
Build & Distribution
Initially, I created a React component with TypeScript, but better thinking about the actual use case, I decided to build the widget as a UMD (Universal Module Definition) module. This allows the widget to be used in various environments, and being framework-agnostic, it can be easily integrated into any JavaScript application, not just React.
I opted for both, ESM and UMD builds, to ensure compatibility with modern JavaScript applications while still supporting older environments that may not fully support ES modules. The project have a example using the UMD in a simple HTML page, and my personal website is using the ESM build, as it is a React application.
Mocking
I tried to mock as little as possible, focusing on the actual implementation of the widget. The widget is designed to be a somewhat real-world solution. The chat is powered by Google's Generative AI, it's lacking fine tuning and pre prompting, but it can be easily extended to include those features in the future.
The actual mock comes in two places:
- User identification: I gather the information but do not use it in the mock. In a real-world scenario, you would use this information to personalize the chat experience. Or initialize the chat with a user ID, so the chat history can be retrieved.
- Maintenence mode: The widget has a maintenance mode, but is randomly triggered in the mock (25% chance). In a real-world scenario I would use a flag to enable or disable the maintenance mode, and use a external service to handle it, such as LaunchDarkly or a similar feature flag service.
State Management
I choose to keep the state management simple, using React's built-in state management with hooks. I didn't see the need for a more complex state management solution like Redux or MobX, as the widget's state is relatively straightforward and doesn't require complex interactions.
In a real-world scenario, if the widget were to grow in complexity or require more advanced state management, I would consider using a state management library like Zustand or React Query. These libraries provide a more scalable solution for managing state in larger applications.
UI
Because the widget is designed to be customizable, I focused on creating a clean and modern UI that can be easily styled by the user. The default styles are minimalistic, allowing users to apply their own styles without conflicts.
I implemented a basic interface for theming, which could be extended in the future to include more customization options. The primary color can be easily changed, and the header can be customized with a title and description.
This was done using CSS variables and tailwindcss, and shadCN, popular and well-maintained libraries that provide a a solid and flexible foundation for styling the widget.
