The @inkeep/uikit package supports React 18, in order to use the Inkeep components with React 17 you can install the @inkeep/uikit-js package.

Quick Start

Install the component library

npm install @inkeep/uikit-js

Define the component

Chat Button

See here for additional supported props.

import { useEffect, useRef } from "react";
import * as inkeepJS from "@inkeep/uikit-js";

const baseSettings = {
  integrationId: process.env.INKEEP_API_KEY,
  apiKey: process.env.INKEEP_INTEGRATION_ID,
  organizationId: process.env.INKEEP_ORGANIZATION_ID,
  primaryBrandColor: "#000000",
};

export const ChatButton = () => {
  const chatButtonRef = useRef(null);

  useEffect(() => {
    const inkeep = inkeepJS.Inkeep(baseSettings);
    chatButtonRef.current = inkeep.embed({
      componentType: "ChatButton",
      targetElement: "#chat-button",
      properties: {
        chatButtonType: "PILL",
        baseSettings,
        aiChatSettings: {
          quickQuestions: ["How to get started?"],
        },
      },
    });
  }, []);

  return <div id="chat-button" />;
};

See here for additional supported props.

import { useEffect, useRef } from "react";
import * as inkeepJS from "@inkeep/uikit-js";

const baseSettings = {
  integrationId: process.env.INKEEP_API_KEY,
  apiKey: process.env.INKEEP_INTEGRATION_ID,
  organizationId: process.env.INKEEP_ORGANIZATION_ID,
  primaryBrandColor: "#000000",
};

export const SearchBar = () => {
  const SearchBarRef = useRef(null);

  useEffect(() => {
    const inkeep = inkeepJS.Inkeep(baseSettings);

    SearchBarRef.current = inkeep.embed({
      componentType: "SearchBar",
      targetElement: "#search-bar-target",
      properties: {
        baseSettings,
        aiChatSettings: {
          quickQuestions: ["How to get started?"],
        },
        // optional -- for syncing UI color mode
        // colorModeSync: {
        //   observedElement: document.documentElement,
        //   isDarkModeCallback: (el) => {
        //     return el.classList.contains("dark");
        //   },
        //   colorModeAttribute: "class",
        // },
      },
    });
  }, []);

  return <div id="search-bar-target" />;
};

Embedded Chat

See here for additional supported props.

import { useEffect, useRef } from "react";
import * as inkeepJS from "@inkeep/uikit-js";

const baseSettings = {
  integrationId: process.env.INKEEP_API_KEY,
  apiKey: process.env.INKEEP_INTEGRATION_ID,
  organizationId: process.env.INKEEP_ORGANIZATION_ID,
  primaryBrandColor: "#805eff",
};

export const EmbeddedChat = () => {
  const embeddedChatRef = useRef(null);

  useEffect(() => {
    const inkeep = inkeepJS.Inkeep(baseSettings);

    embeddedChatRef.current = inkeep.embed({
      componentType: "EmbeddedChat",
      targetElement: "#embedded-chat-target",
      properties: {
        baseSettings,
        aiChatSettings: {
          quickQuestions: ["How to get started?"],
        },
        // optional -- for syncing UI color mode
        // colorModeSync: {
        //   observedElement: document.documentElement,
        //   isDarkModeCallback: (el) => {
        //     return el.classList.contains("dark");
        //   },
        //   colorModeAttribute: "class",
        // },
      },
    });
  }, []);

  return (
    <div className="ikp-wrapper">
      <div id="embedded-chat-target" className="ikp-embedded-chat-wrapper" />
    </div>
  );
};

Custom Trigger

See here for additional supported props.

import { useEffect, useRef, useState } from "react";
import * as inkeepJS from "@inkeep/uikit-js";

const baseSettings = {
  integrationId: process.env.INKEEP_API_KEY,
  apiKey: process.env.INKEEP_INTEGRATION_ID,
  organizationId: process.env.INKEEP_ORGANIZATION_ID,
  primaryBrandColor: "#000000",
};

export const CustomTrigger = () => {
  const CustomTriggerRef = useRef(null);
  const [isOpen, setIsOpen] = useState(false);

  useEffect(() => {
    const inkeep = inkeepJS.Inkeep(baseSettings);

    CustomTriggerRef.current = inkeep.embed({
      componentType: "CustomTrigger",
      properties: {
        baseSettings,
        aiChatSettings: {
          quickQuestions: ["How to get started?"],
        },
        isOpen,
        onClose: () => {
          setIsOpen(false);
        },
        // optional -- for syncing UI color mode
        // colorModeSync: {
        //   observedElement: document.documentElement,
        //   isDarkModeCallback: (el) => {
        //     return el.classList.contains("dark");
        //   },
        //   colorModeAttribute: "class",
        // },
      },
    });
  }, []);

  useEffect(() => {
    if (CustomTriggerRef.current) {
      CustomTriggerRef.current.render({ isOpen });
    }
  }, [isOpen]);

  return (
    <button type="button" onClick={() => setIsOpen(true)}>
      Ask AI
    </button>
  );
};

Server side rendering

If you are using a framework that utilizes server side rendering you will need to import the library asynchronously within a useEffect hook.

Example

This example uses the Chat Button component but the same logic can be applied to any of the other components.

import { useEffect, useRef } from "react";
import { inkeepProps } from "./inkeepSettings";

export const ChatButtonSSR = () => {
  const chatButtonRef = useRef(null);

  useEffect(() => {
    const loadInkeepEmbed = async () => {
      const inkeepEmbed = await import("@inkeep/uikit-js");

      const inkeepChatButtonProps = {
        chatButtonType: "PILL",
        ...inkeepProps,
      };

      const inkeep = inkeepEmbed.Inkeep(inkeepProps.baseSettings);

      chatButtonRef.current = inkeep.embed({
        componentType: "ChatButton",
        targetElement: "#chat-button",
        properties: inkeepChatButtonProps,
      });
    };

    loadInkeepEmbed();
  }, []);

  return <div id="chat-button" />;
};