Google Dialogflow CX Messenger is a powerful conversational AI solution that allows developers to create sophisticated chatbots with minimal backend complexity. This integration specifically demonstrates how to seamlessly embed a Dialogflow chatbot into a Next.js 14 application.
Google Dialogflow CX Messenger
Create a .env.local file in your project root with the following mock configuration:
# Dialogflow CX Configuration
Replace these mock values with your actual Dialogflow CX project details.
NEXT_PUBLIC_DIALOGFLOW_LOCATION=Your Dialogflow project region
NEXT_PUBLIC_DIALOGFLOW_PROJECT_ID=project-demo-123456
NEXT_PUBLIC_DIALOGFLOW_AGENT_ID=abcdef-1234-5678-90ab-cdef12345678
NEXT_PUBLIC_DIALOGFLOW_TITLE=Customer Support
NEXT_PUBLIC_DIALOGFLOW_SUBTITLE=How can I help you today?
NEXT_PUBLIC_DIALOGFLOW_PLACEHOLDER_TEXT=Type your message here...
NEXT_PUBLIC_DIALOGFLOW_LOGO=/path/to/your/logo.png
NEXT_PUBLIC_DIALOGFLOW_BOT_WRITING_TEXT=Our bot is thinking...
NEXT_PUBLIC_DIALOGFLOW_ICON=/path/to/your/bot-icon.png
typeof window !== 'undefined' ensures the code runs only in a browser environment. This is critical because server-side rendering (SSR) doesn't have a window object. !window.dfMessengerLoaded prevents the Dialogflow script from being loaded multiple times. This is important to:
const dfScript = document.createElement('script'); dfScript.src =
'https://www.gstatic.com/dialogflow-console/fast/df-messenger/prod/v1/df-messenger
.js'; dfScript.async = true; dfScript.id = 'dialogflow-messenger-script';
document.head.appendChild(dfScript);
const dfStyles = document.createElement('link'); dfStyles.rel = 'stylesheet';
dfStyles.href = 'https://www.gstatic.com/dialogflow-console/fast/df-messenger/prod/v1/themes
/df-messenger-default.css'; document.head.appendChild(dfStyles);
const styles = document.createElement('style');
styles.textContent = `
df-messenger {
z-index: 999;
position: fixed;
bottom: 36px;
right: 36px;
--df-messenger-font-color: #000;
--df-messenger-font-family: 'Roboto', sans-serif;
--df-messenger-chat-background: #f3f6fc;
--df-messenger-message-user-background: #d3e3fd;
--df-messenger-message-bot-background: #fff;
...rest of the codes
`;
document.head.appendChild(styles);
useEffect(() => {
const messenger = messengerRef.current;
if (messenger) {
const dfMessenger = document.createElement('df-messenger');
dfMessenger.setAttribute('location',process.env.NEXT_PUBLIC_DIALOGFLOW_LOCATION);
...rest of the codes
dfMessenger.appendChild(dfMessengerChat);
messenger.appendChild(dfMessenger);
return () => {
if (messenger) {
messenger.removeChild(dfMessenger);
}
};
}
}, [])\;
This useEffect block is responsible for dynamically creating and configuring the Dialogflow messenger component. Which creates custom web components, sets various attributes that control the messenger's behavior and appearance, establishing the nested structure of the chat interface, ensuring that the component is only mounted when the ref is available, and provides a cleanup method that removes the messenger component when the component unmounts, preventing memory leaks and ensuring clean lifecycle management.
Here's the complete implementation for your reference:
'use client';
import { useEffect, useRef } from 'react';
declare global {
interface Window {
dfMessengerLoaded?: boolean;
}
}
const ChatbotProvider = () => {
const messengerRef = useRef(null);
// Script and style loading logic here (as explained earlier)
useEffect(() => {
const loadDialogflowMessenger = () => {
if (typeof window !== 'undefined' && !window.dfMessengerLoaded) {
const dfScript = document.createElement('script');
dfScript.src =
'https://www.gstatic.com/dialogflow-console/fast/df-messenger/prod/v1/df-messenger.js';
dfScript.async = true;
dfScript.id = 'dialogflow-messenger-script';
document.head.appendChild(dfScript);
window.dfMessengerLoaded = true;
const dfStyles = document.createElement('link');
dfStyles.rel = 'stylesheet';
dfStyles.href =
'https://www.gstatic.com/dialogflow-console/fast/df-messenger/prod/v1/themes/df-messenger-default.css';
document.head.appendChild(dfStyles);
const styles = document.createElement('style');
styles.textContent = `
df-messenger {
z-index: 999;
position: fixed;
bottom: 36px;
right: 36px;
/* General styling */
--df-messenger-font-color: #000;
--df-messenger-font-family: 'Roboto', sans-serif;
--df-messenger-chat-background: #f3f6fc;
--df-messenger-message-user-background: #d3e3fd;
--df-messenger-message-bot-background: #fff;
}
.chat-notice {
position: fixed;
bottom: 25px;
right: 110px;
z-index: 1000;
font-size: 54px;
color: #555;
padding: 10px;
border-radius: 5px;
cursor: pointer;
}
.heading-highlight {
color: rgba(23, 114, 232, 1);
font-weight: bold;
}
.notice {
margin-left: 30px;
font-size: 18px;
font-weight: 500;
color: #555;
padding: 10px;
}
`;
document.head.appendChild(styles);
}
};
loadDialogflowMessenger();
return () => {
const script = document.getElementById('dialogflow-messenger-script');
if (script) {
document.body.removeChild(script);
}
delete window.dfMessengerLoaded;
};
}, []);
// Messenger configuration logic
useEffect(() => {
const messenger = messengerRef.current;
if (messenger) {
const dfMessenger = document.createElement('df-messenger');
dfMessenger.setAttribute('location', process.env.NEXT_PUBLIC_DIALOGFLOW_LOCATION);
dfMessenger.setAttribute('project-id', process.env.NEXT_PUBLIC_DIALOGFLOW_PROJECT_ID);
dfMessenger.setAttribute('agent-id', process.env.NEXT_PUBLIC_DIALOGFLOW_AGENT_ID);
dfMessenger.setAttribute('language-code', 'en');
dfMessenger.setAttribute('max-query-length', '-1');
const dfMessengerChat = document.createElement('df-messenger-chat-bubble');
dfMessengerChat.setAttribute('chat-height', '400');
dfMessengerChat.setAttribute('chat-title', process.env.NEXT_PUBLIC_DIALOGFLOW_TITLE);
dfMessengerChat.setAttribute('chat-subtitle', process.env.NEXT_PUBLIC_DIALOGFLOW_SUBTITLE);
dfMessengerChat.setAttribute('placeholder-text', process.env.NEXT_PUBLIC_DIALOGFLOW_PLACEHOLDER_TEXT);
dfMessengerChat.setAttribute('chat-title-icon', process.env.NEXT_PUBLIC_DIALOGFLOW_LOGO);
dfMessengerChat.setAttribute('bot-writing-text', process.env.NEXT_PUBLIC_DIALOGFLOW_BOT_WRITING_TEXT);
dfMessengerChat.setAttribute('chat-icon', process.env.NEXT_PUBLIC_DIALOGFLOW_ICON);
dfMessenger.appendChild(dfMessengerChat);
messenger.appendChild(dfMessenger);
return () => {
if (messenger) {
messenger.removeChild(dfMessenger);
}
};
}
}, []);
return <div ref={messengerRef} />;
};
export default ChatbotProvider;
Integrating Dialogflow CX Messenger into your Next.js application opens up exciting possibilities for enhanced user interaction. This approach demonstrates how modern web technologies can seamlessly incorporate intelligent conversational interfaces, providing users with responsive, context-aware support at their fingertips.
By leveraging dynamic script loading, extensive customization, and clean component architecture, you're not just adding a chatbot—you're creating a sophisticated, intelligent communication channel that can significantly improve user experience and engagement.
The future of web interactions is conversational, and tools like Dialogflow CX are leading the way!