diff --git a/apps/docs/features/telemetry/telemetry.client.tsx b/apps/docs/features/telemetry/telemetry.client.tsx index b32c4ad9c75..0eb59b33ca7 100644 --- a/apps/docs/features/telemetry/telemetry.client.tsx +++ b/apps/docs/features/telemetry/telemetry.client.tsx @@ -7,7 +7,7 @@ import { useConsent } from 'ui-patterns/ConsentToast' import { IS_PLATFORM } from '~/lib/constants' import { unauthedAllowedPost } from '~/lib/fetch/fetchWrappers' -const useSendPageTelemetryWithConsent = () => { +const useTelemetryWithConsent = () => { const pathname = usePathname() const { hasAcceptedConsent } = useConsent() @@ -34,21 +34,46 @@ const useSendPageTelemetryWithConsent = () => { headers: { Version: '2' }, credentials: 'include', }).catch((e) => { - console.error('Problem sending telemetry:', e) + console.error('Problem sending telemetry page:', e) }) }, [pathname, hasAcceptedConsent]) - return sendPageTelemetry + const sendPageLeaveTelemetry = useCallback(() => { + if (!(IS_PLATFORM && hasAcceptedConsent)) return + + const title = typeof document !== 'undefined' ? document?.title : '' + + unauthedAllowedPost('/platform/telemetry/page-leave', { + body: { + pathname, + page_url: isBrowser ? window.location.href : '', + page_title: title, + }, + credentials: 'include', + }).catch((e) => { + console.error('Problem sending telemetry page-leave:', e) + }) + }, [pathname, hasAcceptedConsent]) + + return { sendPageTelemetry, sendPageLeaveTelemetry } } const PageTelemetry = () => { const pathname = usePathname() - const sendPageTelemetry = useSendPageTelemetryWithConsent() + const { sendPageTelemetry, sendPageLeaveTelemetry } = useTelemetryWithConsent() useEffect(() => { if (pathname) sendPageTelemetry() }, [pathname, sendPageTelemetry]) + useEffect(() => { + if (!pathname) return + + const handleBeforeUnload = () => sendPageLeaveTelemetry() + window.addEventListener('beforeunload', handleBeforeUnload) + return () => window.removeEventListener('beforeunload', handleBeforeUnload) + }, [pathname, sendPageLeaveTelemetry]) + return null } diff --git a/apps/studio/pages/_app.tsx b/apps/studio/pages/_app.tsx index b1c6e7fff68..6c7899c806b 100644 --- a/apps/studio/pages/_app.tsx +++ b/apps/studio/pages/_app.tsx @@ -31,9 +31,8 @@ import relativeTime from 'dayjs/plugin/relativeTime' import timezone from 'dayjs/plugin/timezone' import utc from 'dayjs/plugin/utc' import Head from 'next/head' -import { ErrorInfo, useEffect, useMemo, useRef, useState } from 'react' +import { ErrorInfo, useMemo, useState } from 'react' import { ErrorBoundary } from 'react-error-boundary' -import { toast } from 'sonner' import MetaFaviconsPagesRouter from 'common/MetaFavicons/pages-router' import { AppBannerWrapper, RouteValidationWrapper } from 'components/interfaces/App' @@ -47,9 +46,8 @@ import FlagProvider from 'components/ui/Flag/FlagProvider' import PageTelemetry from 'components/ui/PageTelemetry' import { useRootQueryClient } from 'data/query-client' import { AuthProvider } from 'lib/auth' -import { BASE_PATH, IS_PLATFORM, LOCAL_STORAGE_KEYS } from 'lib/constants' +import { BASE_PATH, IS_PLATFORM } from 'lib/constants' import { ProfileProvider } from 'lib/profile' -import { useAppStateSnapshot } from 'state/app-state' import HCaptchaLoadedStore from 'stores/hcaptcha-loaded-store' import { AppPropsWithLayout } from 'types' import { SonnerToaster } from 'ui' @@ -79,9 +77,7 @@ loader.config({ // the dashboard, all other layout components should not be doing that function CustomApp({ Component, pageProps }: AppPropsWithLayout) { - const snap = useAppStateSnapshot() const queryClient = useRootQueryClient() - const consentToastId = useRef() // [Joshen] Some issues with using createBrowserSupabaseClient const [supabase] = useState(() => diff --git a/apps/www/pages/_app.tsx b/apps/www/pages/_app.tsx index 4720fd4810a..f3308fffbfc 100644 --- a/apps/www/pages/_app.tsx +++ b/apps/www/pages/_app.tsx @@ -88,6 +88,23 @@ export default function App({ Component, pageProps }: AppProps) { } }, [router.isReady, consentValue]) + useEffect(() => { + if (blockEvents) return + + const handleBeforeUnload = async () => { + await post(`${API_URL}/telemetry/page-leave`, { + page_url: window.location.href, + page_title: title, + pathname: router.pathname, + }) + } + window.addEventListener('beforeunload', handleBeforeUnload) + + return () => { + window.removeEventListener('beforeunload', handleBeforeUnload) + } + }, []) + const site_title = `${APP_NAME} | The Open Source Firebase Alternative` const { basePath } = useRouter()