Ui componentsMigrate to cxkit

Migrating from @inkeep/uikit-js to @inkeep/cxkit-js

This guide will help you migrate your JavaScript snippets from using @inkeep/uikit-js to the new @inkeep/cxkit-js package. The new package includes several breaking changes but offers improved functionality and a more consistent API.

Overview

With version 0.5.x, we've renamed our package from @inkeep/uikit-js to @inkeep/cxkit-js to better reflect its purpose as a customer experience toolkit. This change comes with several API improvements and breaking changes that require updates to your code.

Installation

Update your script tag to use the new package:

<!-- Old -->
<script
  type="module"
  src="https://cdn.jsdelivr.net/npm/@inkeep/uikit-js@0.3.20/dist/embed.js"
  defer
></script>
 
<!-- New -->
<script
  type="module"
  src="https://cdn.jsdelivr.net/npm/@inkeep/cxkit-js@^0.5.11/dist/embed.js"
  crossorigin="anonymous"
  defer
></script>

Breaking Changes

Component Initialization Changes

The way components are initialized has changed:

// Old
const inkeepWidget = Inkeep().embed({
  componentType: "ChatButton",
  // ...
});
 
// New
const inkeepWidget = Inkeep.ChatButton({
  // ...
});

Configuration Structure Changes

The configuration structure has been simplified:

// Old
const config = {
  componentType: "ChatButton",
  properties: {
    chatButtonType: "PILL",
    baseSettings: {
      // ...
    },
    aiChatSettings: {
      // ...
    },
    // ...
  },
};
 
// New
const config = {
  // Top-level properties
  baseSettings: {
    // ...
  },
  aiChatSettings: {
    // ...
  },
  // ...
};

Base Settings Changes

Removed Properties

integrationId

The integrationId property has been removed as it's no longer required for authentication. The API key now contains all the necessary information to identify your integration.

// Old
baseSettings: {
  apiKey: "your-api-key",
  integrationId: "your-integration-id",
  // ...
}
 
// New
baseSettings: {
  apiKey: "your-api-key",
  // No integrationId needed
}
organizationId

The organizationId property has been removed as it's no longer required for authentication. The API key now contains all the necessary information to identify your organization.

// Old
baseSettings: {
  apiKey: "your-api-key",
  organizationId: "your-organization-id",
  // ...
}
 
// New
baseSettings: {
  apiKey: "your-api-key",
  // No organizationId needed
}
userType

The userType property has been removed in favor of the more flexible userProperties.cohorts array, which allows you to specify multiple user types or roles.

// Old
baseSettings: {
  userType: "admin",
  // ...
}
 
// New
baseSettings: {
  userProperties: {
    cohorts: ["admin", "engineering"],
    // ...
  },
  // ...
}
remoteErrorLogsLevel

The remoteErrorLogsLevel property has been removed as error logging is now handled internally with improved defaults. If you need custom error handling, use the onError callback.

consoleDebugLevel

The consoleDebugLevel property has been removed as debugging is now handled internally with improved defaults. For development debugging, use the browser's developer tools.

customCardSettings

The customCardSettings property has been removed in favor of the more powerful and flexible transformSource function, which allows for more comprehensive customization of search results.

// Old
baseSettings: {
  customCardSettings: {
    // Custom card settings
  },
  // ...
}
 
// New
baseSettings: {
  transformSource: (source) => {
    // Transform source data
    return {
      ...source,
      tabs: [] // Transform tabs
    };
  },
  // ...
}

See Source Transformation for more details.

The breadcrumbRules property has been removed in favor of the more powerful and flexible transformSource function, which allows for more comprehensive customization of breadcrumbs.

// Old
baseSettings: {
  breadcrumbRules: [
    // Breadcrumb rules
  ],
  // ...
}
 
// New
baseSettings: {
  transformSource: (source) => {
    // Transform breadcrumbs
    return {
      ...source,
      breadcrumbs: []
    };
  },
  // ...
}

See Source Transformation for more details.

stringReplacementRules

The stringReplacementRules property has been removed in favor of the more powerful and flexible transformSource function, which allows for more comprehensive string transformations.

// Old
baseSettings: {
  stringReplacementRules: [
    // String replacement rules
  ],
  // ...
}
 
// New
baseSettings: {
  transformSource: (source) => {
    // Transform source data
    return {
      ...source,
      breadcrumbs: []
    };
  },
  // ...
}

See Source Transformation for more details.

Renamed Properties

User Properties

User properties are now grouped under userProperties:

// Old
baseSettings: {
  userId: "user-456",
  userEmail: "jane@enterprise.com",
  userName: "Jane Smith",
  // ...
}
 
// New
baseSettings: {
  userProperties: {
    id: "user-456",
    email: "jane@enterprise.com",
    name: "Jane Smith",
    cohorts: ["admin", "engineering"],
  },
  // ...
}
Authentication Token

userTokenuserAuthToken

// Old
baseSettings: {
  userToken: "jwt-token-for-user-authentication",
  // ...
}
 
// New
baseSettings: {
  userAuthToken: "jwt-token-for-user-authentication",
  // ...
}
Event Handling

logEventCallbackonEvent (with updated event structure)

// Old
baseSettings: {
  logEventCallback: (event) => {
    // Handle event
    console.log(event);
  },
  // ...
}
 
// New
baseSettings: {
  onEvent: (event) => {
    // Handle event
    console.log(event);
  },
  // ...
}
Privacy Preferences

Privacy preferences are now grouped:

// Old
baseSettings: {
  optOutAnalyticalCookies: false,
  optOutAllAnalytics: false,
  optOutFunctionalCookies: false,
  // ...
}
 
// New
baseSettings: {
  privacyPreferences: {
    optOutAnalyticalCookies: false,
    optOutAllAnalytics: false,
    optOutFunctionalCookies: false,
  },
  // ...
}
API Endpoints
  • chatApiProxyDomainaiApiBaseUrl
  • analyticsApiProxyDomainanalyticsApiBaseUrl
// Old
baseSettings: {
  chatApiProxyDomain: "https://api.inkeep.com/chat",
  analyticsApiProxyDomain: "https://api.example.com/analytics",
  // ...
}
 
// New
baseSettings: {
  aiApiBaseUrl: "https://api.inkeep.com/chat",
  analyticsApiBaseUrl: "https://api.example.com/analytics",
  // ...
}
Environment Configuration

env options are now lowercase: "development" | "production"

// Old
baseSettings: {
  env: "DEVELOPMENT",
  // ...
}
 
// New
baseSettings: {
  env: "development",
  // ...
}
URL Parameters

appendQueryParamsToUrlsurlQueryParamsToAppend

// Old
baseSettings: {
  appendQueryParamsToUrls: { utm_source: "docs" },
  // ...
}
 
// New
baseSettings: {
  urlQueryParamsToAppend: { utm_source: "docs" },
  // ...
}
Styling

stylesheets and stylesheetUrlsstyles

// Old
baseSettings: {
  stylesheets: ["custom-styles.css"],
  stylesheetUrls: ["https://example.com/styles.css"],
  // ...
}
 
// New
baseSettings: {
  styles: [
    {
      key: "google-fonts",
      type: "link",
      value: "https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap",
    },
    {
      key: "custom-theme",
      type: "style",
      value: `
        .ikp-ai-chat-message {
          border-radius: 8px;
          padding: 12px;
        }
        [data-theme='dark'] .ikp-ai-chat-message {
          background: #2D3748;
        }
      `,
    },
  ],
  // ...
}

Color Mode Synchronization

The color mode synchronization has been updated:

// Old
colorModeSync: {
  observedElement: document.documentElement,
  isDarkModeCallback: (el) => {
    return el.classList.contains("dark");
  },
  colorModeAttribute: "class",
}
 
// New
baseSettings: {
  colorMode: {
    sync: {
      target: document.documentElement,
      attributes: ["data-theme"],
      isDarkMode: (attributes) => attributes["data-theme"] === "dark",
    }
  }
}

AI Chat Settings Changes

Removed Properties

isControlledMessage

The isControlledMessage property has been removed as the component now uses a more intuitive controlled/uncontrolled pattern. Use the defaultMessage prop for uncontrolled behavior or the message and onInputMessageChange props for controlled behavior.

includeAIAnnotations

The includeAIAnnotations property has been removed as annotations are now handled internally with improved defaults. Equivalent functionality will be available in a future release.

aiAnnotationPolicies

The aiAnnotationPolicies property has been removed as annotation policies are now handled internally with improved defaults. Equivalent functionality will be available in a future release.

Renamed Properties

Assistant Name and Avatar
  • botNameaiAssistantName

  • botAvatarSrcUrlaiAssistantAvatar

  • botAvatarDarkSrcUrl → can be configured by changing aiAssistantAvatar to an object:

    // Old
    aiChatSettings: {
      botAvatarSrcUrl: "/assets/assistant.png",
      botAvatarDarkSrcUrl: "/assets/assistant-dark.png",
      // ...
    }
     
    // New
    aiChatSettings: {
      aiAssistantAvatar: {
        light: "/assets/assistant-light.png",
        dark: "/assets/assistant-dark.png"
      },
      // ...
    }
User Avatar
  • userAvatarSrcUrluserAvatar
// Old
aiChatSettings: {
  userAvatarSrcUrl: userProfile.avatarUrl,
  // ...
}
 
// New
aiChatSettings: {
  userAvatar: userProfile.avatarUrl,
  // ...
}
Example Questions
  • quickQuestionsexampleQuestions
  • quickQuestionsLabelexampleQuestionsTitle
  • shouldHighlightFirstQuickQuestionisFirstExampleQuestionHighlighted
// Old
aiChatSettings: {
  quickQuestions: ["What is the capital of France?", "What is the capital of Germany?"],
  quickQuestionsLabel: "Example Questions",
  shouldHighlightFirstQuickQuestion: true,
  // ...
}
 
// New
aiChatSettings: {
  exampleQuestions: ["What is the capital of France?", "What is the capital of Germany?"],
  exampleQuestionsTitle: "Example Questions",
  isFirstExampleQuestionHighlighted: true,
  // ...
}
Disclaimer Settings

Disclaimer settings properties have been renamed:

// Old
aiChatSettings: {
  disclaimerSettings: {
    isDisclaimerEnabled: true,
    disclaimerLabel: "Usage policy",
    disclaimerTooltip: "Information provided by AI is not guaranteed to be accurate.",
  },
  // ...
}
 
// New
aiChatSettings: {
  disclaimerSettings: {
    isEnabled: true,
    label: "Usage policy",
    tooltip: "Information provided by AI is not guaranteed to be accurate.",
  },
  // ...
}
Input Handling
  • handleMessageChangeonInputMessageChange
// Old
aiChatSettings: {
  handleMessageChange: (message) => {
    // Handle message change
    console.log(message);
  },
  // ...
}
 
// New
aiChatSettings: {
  onInputMessageChange: (message) => {
    // Handle message change
    console.log(message);
  },
  // ...
}
Help Options
  • getHelpCallToActionsgetHelpOptions
// Old
aiChatSettings: {
  getHelpCallToActions: () => {
    // Get help call to actions
    return [
      {
        icon: { builtIn: 'FaDiscord' },
        name: 'Discord',
        url: 'https://inkeep.com/',
      },
    ];
  },
  // ...
}
 
// New
aiChatSettings: {
  getHelpOptions: () => {
    // Get help options
    return [
      {
        name: 'Discord',
        icon: {
          builtIn: 'FaDiscord',
        },
        action: {
          type: 'open_link',
          url: 'https://inkeep.com/',
        },
      },
    ];
  },
  // ...
}
Form Configuration

Form configuration has been updated with improved structuring. See Form Settings for details:

// Old
aiChatSettings: {
  formConfig: {
    // Basic form configuration
    fields: [
      {
        type: "text",
        name: "name",
        label: "Name",
      },
    ],
  },
  // ...
}
 
// New
aiChatSettings: {
  formSettings: {
    // Improved form settings structure
    fields: [
      {
        type: "text",
        name: "name",
        label: "Name",
        validation: {
          required: true,
          minLength: 2,
        },
      },
    ],
    submitButton: {
      label: "Submit",
    },
    onSubmit: (data) => {
      console.log("Form submitted:", data);
    },
  },
  // ...
}
Sharing and Toolbar
  • isChatSharingEnabledisShareButtonVisible
  • shouldShowCopyChatButtonisCopyChatButtonVisible
  • actionButtonLabelstoolbarButtonLabels
// Old
aiChatSettings: {
  isChatSharingEnabled: true,
  shouldShowCopyChatButton: true,
  actionButtonLabels: {
    copy: "Copy Chat",
    share: "Share Chat",
    // ...
  },
  // ...
}
 
// New
aiChatSettings: {
  isShareButtonVisible: true,
  isCopyChatButtonVisible: true,
  toolbarButtonLabels: {
    copy: "Copy Chat",
    share: "Share Chat",
    // ...
  },
  // ...
}
Prompts
  • context and guidance → use prompts instead
// Old
aiChatSettings: {
  context: "The user is new to the product.",
  guidance: "Be concise.",
  // ...
}
 
// New
aiChatSettings: {
  prompts: [
    "The user is new to the product.",
    "Be concise."
  ],
  // ...
}

Search Settings Changes

Removed Properties

isControlledSearchQuery

The isControlledSearchQuery property has been removed as the component now uses a more intuitive controlled/uncontrolled pattern. Use the defaultQuery prop for uncontrolled behavior or the query and onQueryChange props for controlled behavior.

Renamed Properties

prefilledQuery

The prefilledQuery property has been renamed to defaultQuery for improved clarity and consistency:

// Old
searchSettings: {
  prefilledQuery: "How to get started",
  // ...
}
 
// New
searchSettings: {
  defaultQuery: "How to get started",
  // ...
}
handleSearchQueryChange

The handleSearchQueryChange property has been renamed to onQueryChange for improved clarity:

// Old
searchSettings: {
  handleSearchQueryChange: (query) => {
    // Handle query change
    console.log(query);
  },
  // ...
}
 
// New
searchSettings: {
  onQueryChange: (query) => {
    // Handle query change
    console.log(query);
  },
  // ...
}
tabSettings

The tabSettings property has been renamed to tabs for improved clarity and simplicity. See docs here for more details:

// Old
searchSettings: {
  tabSettings: {
    isAllTabEnabled: true,
    rootBreadcrumbsToUseAsTabs: ['Docs'],
    tabOrderByLabel: ['Resources', 'Blog', 'Solutions'],
    disabledDefaultTabs: undefined, // string[] | undefined
    alwaysDisplayedTabs: ['Blog'],
  },
  // ...
}
 
// New
searchSettings: {
  // Basic tabs
  tabs: ["All", "Publications", "GitHub", "Forums"],
 
  // With always visible option
  tabs: [
    "All",
    "Publications",
    ["GitHub", { isAlwaysVisible: true }],
    "Forums",
  ],
 
  // Hide "All" tab, show only Publications and GitHub
  tabs: ["Publications", "GitHub"],
 
  // No tabs (just show all results)
  tabs: [],
  // ...
}
maximumHitsLimit

The maximumHitsLimit property has been renamed to maxResults for improved clarity:

// Old
searchSettings: {
  maximumHitsLimit: 10,
  // ...
}
 
// New
searchSettings: {
  maxResults: 10,
  // ...
}
debounceTime

The debounceTime property has been renamed to debounceTimeMs for improved clarity:

// Old
searchSettings: {
  debounceTime: 500,
  // ...
}
 
// New
searchSettings: {
  debounceTimeMs: 500,
  // ...
}
shouldShowAskAICard

The shouldShowAskAICard property has been elevated to a top-level property:

// Old
searchSettings: {
  shouldShowAskAICard: true,
  // ...
}
 
// New
shouldShowAskAICard: true, // Now a top-level property

Removed Properties

isShortcutKeyEnabled

The isShortcutKeyEnabled property has been removed. To disable the shortcut key, pass shortcutKey as null, or pass a key to enable it:

// Old
modalSettings: {
  isShortcutKeyEnabled: false,
  // ...
}
 
// New
modalSettings: {
  shortcutKey: null, // Disables the shortcut key
  // ...
}
isAlignedToTop

The isAlignedToTop property has been removed as modal positioning is now handled through CSS.

isAlignedToRight

The isAlignedToRight property has been removed as modal positioning is now handled through CSS.

onShortcutKeyPressed

The onShortcutKeyPressed property has been removed as shortcut key handling is now managed internally.

Renamed Properties

openShortcutKey

The openShortcutKey property has been renamed to shortcutKey for improved clarity:

// Old
modalSettings: {
  openShortcutKey: "k",
  // ...
}
 
// New
modalSettings: {
  shortcutKey: "k",
  // ...
}
askAILabel

The askAILabel property has been moved to be a top-level property:

// Old
modalSettings: {
  askAILabel: "Ask AI",
  // ...
}
 
// New
askAILabel: "Ask AI", // Now a top-level property
switchToSearchMessage

The switchToSearchMessage property has been renamed to searchLabel and moved to be a top-level property:

// Old
modalSettings: {
  switchToSearchMessage: "Search Documentation",
  // ...
}
 
// New
searchLabel: "Search Documentation", // Now a top-level property
isModeSwitchingEnabled

The isModeSwitchingEnabled property has been renamed to canToggleView and moved to be a top-level property:

// Old
modalSettings: {
  isModeSwitchingEnabled: true,
  // ...
}
 
// New
canToggleView: true, // Now a top-level property
forceInitialDefaultView

The forceInitialDefaultView property has been renamed to forceDefaultView and moved to be a top-level property:

// Old
modalSettings: {
  forceInitialDefaultView: "search",
  // ...
}
 
// New
forceDefaultView: "search", // Now a top-level property

Chat Button Changes

Removed Properties

chatButtonType

The chatButtonType property has been removed as the button appearance can now be customized via CSS using the provided class names.

chatButtonBgColor

The chatButtonBgColor property has been removed as the button background color can now be customized via CSS using the .ikp-chat-button__button class.

.ikp-chat-button__button {
  background-color: #4a5568;
}
chatButtonBgColorDarkMode

The chatButtonBgColorDarkMode property has been removed as the button background color in dark mode can now be customized via CSS using the [data-theme='dark'] .ikp-chat-button__button selector.

[data-theme="dark"] .ikp-chat-button__button {
  background-color: #2d3748;
}
isPositionFixed

The isPositionFixed property has been removed as the button positioning can now be customized via CSS by setting position: relative; on the .ikp-chat-button__container class.

.ikp-chat-button__container {
  position: relative;
}
fixedPositionXOffset

The fixedPositionXOffset property has been removed as the button horizontal positioning can now be customized via CSS by setting right: 0; on the .ikp-chat-button__container class.

.ikp-chat-button__container {
  right: 0;
}
fixedPositionYOffset

The fixedPositionYOffset property has been removed as the button vertical positioning can now be customized via CSS by setting bottom: 0; on the .ikp-chat-button__container class.

.ikp-chat-button__container {
  bottom: 0;
}

Renamed Properties

Button Label
  • chatButtonTextlabel
// Old
chatButtonSettings: {
  chatButtonText: "Chat with AI",
  // ...
}
 
// New
chatButtonSettings: {
  label: "Chat with AI",
  // ...
}

Example Migration

Before (with @inkeep/uikit-js)

<script type="module">
  import "https://cdn.jsdelivr.net/npm/@inkeep/uikit-js@0.3.20/dist/embed.js";
 
  document.addEventListener("DOMContentLoaded", () => {
    const inkeepWidget = Inkeep().embed({
      componentType: "ChatButton",
      colorModeSync: {
        observedElement: document.documentElement,
        isDarkModeCallback: (el) => {
          return el.classList.contains("dark");
        },
        colorModeAttribute: "class",
      },
      properties: {
        chatButtonType: "PILL",
        baseSettings: {
          apiKey: "INKEEP_API_KEY",
          integrationId: "INKEEP_INTEGRATION_ID",
          organizationId: "INKEEP_ORGANIZATION_ID",
          primaryBrandColor: "#26D6FF",
          organizationDisplayName: "Inkeep",
          userId: "user-123",
          userEmail: "user@example.com",
          userName: "John Doe",
        },
        aiChatSettings: {
          botName: "Support Bot",
          botAvatarSrcUrl: "/bot-avatar.png",
          botAvatarDarkSrcUrl: "/bot-avatar-dark.png",
          quickQuestions: [
            "How do I get started?",
            "What are the pricing plans?",
            "How do I contact support?",
          ],
        },
      },
    });
  });
</script>

After (with @inkeep/cxkit-js)

<script type="module">
  import "https://cdn.jsdelivr.net/npm/@inkeep/cxkit-js@0.5.11/dist/embed.js";
 
  document.addEventListener("DOMContentLoaded", () => {
    const inkeepWidget = Inkeep.ChatButton({
      baseSettings: {
        apiKey: "INKEEP_API_KEY",
        primaryBrandColor: "#26D6FF",
        organizationDisplayName: "Inkeep",
        userProperties: {
          id: "user-123",
          email: "user@example.com",
          name: "John Doe",
        },
        colorMode: {
          sync: {
            target: document.documentElement,
            attributes: ["class"],
            isDarkMode: (attributes) => attributes["class"]?.includes("dark"),
          },
        },
      },
      aiChatSettings: {
        aiAssistantName: "Support Bot",
        aiAssistantAvatar: {
          light: "/bot-avatar.png",
          dark: "/bot-avatar-dark.png",
        },
        exampleQuestions: [
          "How do I get started?",
          "What are the pricing plans?",
          "How do I contact support?",
        ],
      },
      label: "Ask AI",
    });
  });
</script>

API Keys

Production API keys for web integrations now require Enforce referrer URL to be enabled for additional security. API keys without this setting will be severely rate limited. See Public API Keys for more details.

New Features

The new package includes several new features:

Need Help?

If you encounter any issues during migration, please contact our support team for assistance.

On this page