Google Dialogflow CX Messenger integration Nextjs 14

Google Dialogflow CX Messenger integration Nextjs 14

An Overview of Google Dialogflow CX Messenger

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

Environment Variables Configuration

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

Detailed Code Explanation

Conditional Script Loading

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:

  • Avoid unnecessary network requests
  • Prevent potential script conflicts
  • Optimize performance
  • Ensure clean script management

Script Creation Process

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);
  • Dynamically creates a <script> element
  • Sets the source to Dialogflow's messenger script
  • Marks it as asynchronous for non-blocking loading
  • Adds a unique identifier
  • Appends to the document head
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);
  • Creates a <link> element for default Dialogflow styles
  • Ensures consistent base styling across different browsers
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.

Entire Code Reference

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;

Conclusion

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!

"CODIMITE" Would Like To Send You Notifications
Our notifications keep you updated with the latest articles and news. Would you like to receive these notifications and stay connected ?
Not Now
Yes Please