Scenario

In some cases, based on end-user location/preferences you may want to disable some analytics/cookies. In order to achieve this, you need to modify these widget configuration properties:

PropertyTypeDescription
optOutAnalyticalCookiesbooleanOption to disable cookies used for tracking a user's Inkeep usage behavior across multiple browser sessions. Only same-domain cookies are used. Default: false.
optOutAllAnalyticsbooleanOption to disable all usage analytics, even anonymous ones. Default: false.
optOutFunctionalCookiesbooleanOption to disable cookies that are used for functionality. Default: false.
remoteErrorLogsLevelRemoteErrorLogsLevelThe level of remote error logging for Inkeep's monitoring service. Default: RemoteErrorLogsLevel.IdentifiableErrors.

In the example below we have a single checkbox where the user can opt out of all analytics. This pattern can be used more granularly to map your own customer preference system to ours.

Example

Parent component:

import { ChangeEvent, useState } from "react";
import InkeepChatButton from "./components/InkeepChatButton";
import { RemoteErrorLogsLevel } from "@inkeep/widgets";

function ParentComponent() {
  const [optOutAnalytics, setOptOutAnalytics] = useState(false);

  const handleChangeCheckbox = (e: ChangeEvent<HTMLInputElement>) => {
    setOptOutAnalytics(e.target.checked);
  };

  return (
    <>
      <InkeepChatButton
        inkeepPrivacyProperties={{
          optOutAnalyticalCookies: optOutAnalytics,
          optOutAllAnalytics: optOutAnalytics,
          optOutFunctionalCookies: optOutAnalytics,
          remoteErrorLogsLevel: optOutAnalytics
            ? RemoteErrorLogsLevel.None
            : RemoteErrorLogsLevel.IdentifiableErrors,
        }}
      />
      {/* ... */}
      <input
        type="checkbox"
        checked={optOutAnalytics}
        id="optOutAnalytics"
        onChange={handleChangeCheckbox}
      />
      <label htmlFor="optOutAnalytics">Opt out of all analytics</label>
      {/* ... */}
    </>
  );
}

export default ParentComponent;

Widget component:

import {
  type InkeepChatButtonProps,
  type InkeepWidgetBaseSettings,
  type RemoteErrorLogsLevel,
} from "@inkeep/widgets";
import { memo, useEffect, useState } from "react";

const baseSettings: InkeepWidgetBaseSettings = {
  apiKey: process.env.INKEEP_INTEGRATION_API_KEY!,
  integrationId: process.env.INKEEP_INTEGRATION_ID!,
  organizationId: process.env.INKEEP_ORGANIZATION_ID!,
  organizationDisplayName: "Inkeep",
  primaryBrandColor: "#26D6FF",
};

interface InkeepPrivacyProperties {
  optOutAnalyticalCookies: boolean;
  optOutAllAnalytics: boolean;
  optOutFunctionalCookies: boolean;
  remoteErrorLogsLevel: RemoteErrorLogsLevel;
}

interface IProps {
  inkeepPrivacyProperties: InkeepPrivacyProperties;
}

function InkeepChatButton({ inkeepPrivacyProperties }: IProps) {
  const [ChatButton, setChatButton] =
    useState<React.FC<InkeepChatButtonProps>>();

  useEffect(() => {
    const loadChatButton = async () => {
      try {
        const { InkeepChatButton } = await import("@inkeep/widgets");
        setChatButton(() => InkeepChatButton);
      } catch (error) {
        console.error("Failed to load ChatButton:", error);
      }
    };

    loadChatButton();
  }, []);

  const chatButtonProps: InkeepChatButtonProps = {
    baseSettings: {
      ...baseSettings,
      ...inkeepPrivacyProperties,
    },
    aiChatSettings: {
      // optional settings
    },
    searchSettings: {
      // optional settings
    },
    modalSettings: {
      // optional settings
    },
  };

  return ChatButton ? <ChatButton {...chatButtonProps} /> : <></>;
}

// use memo to avoid component re-rendering
export default memo(InkeepChatButton);