diff --git a/apps/web/.env.example b/apps/web/.env.example
index 424cd658..dd87b26d 100644
--- a/apps/web/.env.example
+++ b/apps/web/.env.example
@@ -102,5 +102,8 @@ NEXT_PUBLIC_INTERCOM_APP_ID=
# Zendesk Config
NEXT_PUBLIC_ZENDESK_KEY=
+# Help Scout Config
+NEXT_PUBLIC_HELPSCOUT_KEY=
+
# Set it to "1" if you need to run E2E tests locally
NEXT_PUBLIC_IS_E2E=
diff --git a/apps/web/components/Shell.tsx b/apps/web/components/Shell.tsx
index 548f57c7..6feb6a50 100644
--- a/apps/web/components/Shell.tsx
+++ b/apps/web/components/Shell.tsx
@@ -26,8 +26,7 @@ import Dropdown, {
} from "@calcom/ui/Dropdown";
import LicenseBanner from "@ee/components/LicenseBanner";
import TrialBanner from "@ee/components/TrialBanner";
-import IntercomMenuItem from "@ee/lib/intercom/IntercomMenuItem";
-import ZendeskMenuItem from "@ee/lib/zendesk/ZendeskMenuItem";
+import HelpMenuItem from "@ee/components/support/HelpMenuItem";
import classNames from "@lib/classNames";
import { NEXT_PUBLIC_BASE_URL } from "@lib/config/constants";
@@ -490,8 +489,9 @@ function UserDropdown({ small }: { small?: boolean }) {
{t("visit_roadmap")}
-
-
+
+
+
+
+
+
+ >
+ );
+}
diff --git a/apps/web/ee/lib/helpscout/HelpscoutMenuItem.tsx b/apps/web/ee/lib/helpscout/HelpscoutMenuItem.tsx
new file mode 100644
index 00000000..f41c251e
--- /dev/null
+++ b/apps/web/ee/lib/helpscout/HelpscoutMenuItem.tsx
@@ -0,0 +1,42 @@
+import { ChatAltIcon } from "@heroicons/react/solid";
+import { useState } from "react";
+import { HelpScout, useChat } from "react-live-chat-loader";
+
+import { useLocale } from "@calcom/lib/hooks/useLocale";
+import { DropdownMenuItem } from "@calcom/ui/Dropdown";
+
+import classNames from "@lib/classNames";
+
+export default function HelpscoutMenuItem() {
+ const { t } = useLocale();
+ const [active, setActive] = useState(false);
+
+ const [state, loadChat] = useChat();
+
+ function handleClick() {
+ setActive(true);
+ loadChat({ open: true });
+ }
+
+ if (!process.env.NEXT_PUBLIC_HELPSCOUT_KEY) return null;
+ else
+ return (
+ <>
+
+
+
+ {active && }
+ >
+ );
+}
diff --git a/apps/web/ee/lib/helpscout/provider.tsx b/apps/web/ee/lib/helpscout/provider.tsx
new file mode 100644
index 00000000..fcd50416
--- /dev/null
+++ b/apps/web/ee/lib/helpscout/provider.tsx
@@ -0,0 +1,10 @@
+import { FC } from "react";
+import { LiveChatLoaderProvider } from "react-live-chat-loader";
+
+const Provider: FC = ({ children }) => (
+
+ <>{children}>
+
+);
+
+export default Provider;
diff --git a/apps/web/ee/lib/helpscout/providerDynamic.tsx b/apps/web/ee/lib/helpscout/providerDynamic.tsx
new file mode 100644
index 00000000..1849904a
--- /dev/null
+++ b/apps/web/ee/lib/helpscout/providerDynamic.tsx
@@ -0,0 +1,8 @@
+import dynamic from "next/dynamic";
+import { Fragment } from "react";
+
+const DynamicHelpscoutProvider = process.env.NEXT_PUBLIC_HELPSCOUT_KEY
+ ? dynamic(() => import("./provider"))
+ : Fragment;
+
+export default DynamicHelpscoutProvider;
diff --git a/apps/web/ee/lib/zendesk/ZendeskMenuItem.tsx b/apps/web/ee/lib/zendesk/ZendeskMenuItem.tsx
index bc2bb6b4..5fc66132 100644
--- a/apps/web/ee/lib/zendesk/ZendeskMenuItem.tsx
+++ b/apps/web/ee/lib/zendesk/ZendeskMenuItem.tsx
@@ -2,10 +2,10 @@ import { ChatAltIcon } from "@heroicons/react/solid";
import Script from "next/script";
import { useState } from "react";
+import { useLocale } from "@calcom/lib/hooks/useLocale";
import { DropdownMenuItem } from "@calcom/ui/Dropdown";
import classNames from "@lib/classNames";
-import { useLocale } from "@lib/hooks/useLocale";
const ZENDESK_KEY = process.env.NEXT_PUBLIC_ZENDESK_KEY;
diff --git a/apps/web/lib/app-providers.tsx b/apps/web/lib/app-providers.tsx
index c8381599..2d96b261 100644
--- a/apps/web/lib/app-providers.tsx
+++ b/apps/web/lib/app-providers.tsx
@@ -3,7 +3,10 @@ import { SessionProvider } from "next-auth/react";
import { appWithTranslation } from "next-i18next";
import type { AppProps as NextAppProps } from "next/app";
import React, { ComponentProps, ReactNode } from "react";
+import { LiveChatLoaderProvider } from "react-live-chat-loader";
+import { HelpScout } from "react-live-chat-loader";
+import DynamicHelpscoutProvider from "@ee/lib/helpscout/providerDynamic";
import DynamicIntercomProvider from "@ee/lib/intercom/providerDynamic";
import usePublicPage from "@lib/hooks/usePublicPage";
@@ -55,7 +58,9 @@ const AppProviders = (props: AppPropsWithChildren) => {
{isPublicPage ? (
RemainingProviders
) : (
- {RemainingProviders}
+
+ {RemainingProviders}
+
)}
diff --git a/apps/web/package.json b/apps/web/package.json
index 277784f6..6a654176 100644
--- a/apps/web/package.json
+++ b/apps/web/package.json
@@ -87,6 +87,7 @@
"react-hook-form": "^7.20.4",
"react-hot-toast": "^2.1.0",
"react-intl": "^5.22.0",
+ "react-live-chat-loader": "^2.7.3",
"react-multi-email": "^0.5.3",
"react-phone-number-input": "^3.1.41",
"react-query": "^3.33.7",
diff --git a/apps/web/styles/globals.css b/apps/web/styles/globals.css
index 840d3a2c..f976a14b 100644
--- a/apps/web/styles/globals.css
+++ b/apps/web/styles/globals.css
@@ -165,12 +165,23 @@ button[role="switch"][data-state="checked"] span {
/* hide chat bubble on mobile */
@media only screen and (max-width: 768px) {
+ /* Intercom FAB*/
#launcher {
display: none !important;
}
+
+ /* Zendesk FAB*/
div[role="presentation"] > iframe {
display: none !important;
}
+
+ /* Helpscout FAB*/
+ .BeaconFabButtonFrame {
+ margin-left: -30px;
+ left: 50%;
+ bottom: 28px !important;
+ z-index: 1058 !important;
+ }
}
/* add padding bottom to bottom nav on standalone mode */
diff --git a/apps/website b/apps/website
index 0c5841db..e54a7cc0 160000
--- a/apps/website
+++ b/apps/website
@@ -1 +1 @@
-Subproject commit 0c5841db96243e93ffda5cc6c26a1ea89b4bd1e3
+Subproject commit e54a7cc0ecbb36a5a6838f77d8c19ec008c8849a