From b241c29afaff5b7fccc5f7c2e537fa7642aa56a3 Mon Sep 17 00:00:00 2001 From: protobuf-ci-cd Date: Fri, 18 Jul 2025 18:00:12 +0200 Subject: [PATCH] feat(analytics): add timeout option to unblock in case of silent failure (thanks to Brave browser) Signed-off-by: protobuf-ci-cd --- .changeset/crazy-suits-kneel.md | 5 ++++ .../src/analytics/useAnalytics.tsx | 23 ++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 .changeset/crazy-suits-kneel.md diff --git a/.changeset/crazy-suits-kneel.md b/.changeset/crazy-suits-kneel.md new file mode 100644 index 000000000..1deaa540a --- /dev/null +++ b/.changeset/crazy-suits-kneel.md @@ -0,0 +1,5 @@ +--- +"@scaleway/use-analytics": patch +--- + +add a timeout option to set analytics in case of silent failure diff --git a/packages/use-analytics/src/analytics/useAnalytics.tsx b/packages/use-analytics/src/analytics/useAnalytics.tsx index 5a7f180b3..d1317d6d4 100644 --- a/packages/use-analytics/src/analytics/useAnalytics.tsx +++ b/packages/use-analytics/src/analytics/useAnalytics.tsx @@ -1,6 +1,6 @@ import { RudderAnalytics } from '@rudderstack/analytics-js' import type { LoadOptions } from '@rudderstack/analytics-js' -import { createContext, useContext, useMemo, useState } from 'react' +import { createContext, useContext, useEffect, useMemo, useState } from 'react' import type { ReactNode } from 'react' import { useDeepCompareEffectNoCheck } from 'use-deep-compare-effect' import { destSDKBaseURL, pluginsSDKBaseURL } from '../constants' @@ -51,6 +51,7 @@ export type AnalyticsProviderProps = { settings?: { writeKey: string cdnURL: string + timeout: number } loadOptions?: LoadOptions @@ -92,6 +93,26 @@ export function AnalyticsProvider({ undefined, ) + // This effect will unlock the case where we have a failure with the load of the analytics.load as rudderstack doesn't provider any solution for this case. + useEffect(() => { + let timer: ReturnType | undefined + if (!isAnalyticsReady && !internalAnalytics && settings?.timeout) { + if (shouldRenderOnlyWhenReady) { + timer = setTimeout(() => setIsAnalyticsReady(true), settings.timeout) + } + } + + return () => { + clearTimeout(timer) + } + }, [ + isAnalyticsReady, + internalAnalytics, + setIsAnalyticsReady, + shouldRenderOnlyWhenReady, + settings?.timeout, + ]) + const shouldLoad = useMemo(() => { if (needConsent) { return false