Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/good-pears-help.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@scaleway/use-analytics": patch
---

fix issue with destination load and naming
43 changes: 30 additions & 13 deletions biome.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,23 @@
{
"$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
"organizeImports": { "enabled": false },
"linter": { "enabled": false },
"assist": { "actions": { "source": { "organizeImports": "off" } } },
"linter": {
"enabled": false,
"rules": {
"style": {
"noParameterAssign": "error",
"useAsConstAssertion": "error",
"useDefaultParameterLast": "error",
"useEnumInitializers": "error",
"useSelfClosingElements": "error",
"useSingleVarDeclarator": "error",
"noUnusedTemplateLiteral": "error",
"useNumberNamespace": "error",
"noInferrableTypes": "error",
"noUselessElse": "error"
}
}
},
"vcs": {
"clientKind": "git",
"useIgnoreFile": true
Expand All @@ -14,17 +30,18 @@
"lineEnding": "lf",
"lineWidth": 80,
"attributePosition": "auto",
"ignore": [
".next/",
"coverage/",
"**/node_modules/",
"**/storybook-static",
"**/dist/",
"**/pnpm-lock.yaml",
"**/package.json",
"**/CHANGELOG.md",
"*.snap",
"**/__snapshots__/"
"includes": [
"**",
"!**/.next/",
"!**/coverage/",
"!**/node_modules/",
"!**/storybook-static",
"!**/dist/",
"!**/pnpm-lock.yaml",
"!**/package.json",
"!**/CHANGELOG.md",
"!**/*.snap",
"!**/__snapshots__/"
]
},
"javascript": {
Expand Down
4 changes: 2 additions & 2 deletions packages/use-analytics/src/analytics/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export const defaultConsentOptions: ConsentOptions = {
trackConsent: true,
discardPreConsentEvents: true,
storage: {
type: 'localStorage',
type: 'cookieStorage',
},
consentManagement: {
enabled: true,
Expand Down Expand Up @@ -47,7 +47,7 @@ export const defaultLoadOptions: LoadOptions = {
integrations: {
All: true,
},
loadIntegration: false,
loadIntegration: true,
secureCookie: true,
anonymousIdOptions: {
autoCapture: {
Expand Down
40 changes: 31 additions & 9 deletions packages/use-analytics/src/analytics/useAnalytics.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,13 @@
loadOptions?: LoadOptions

/**
* This option help you in case you don't want to load analytics
* This option force provider to render children only when isAnalytics is ready
*/
shouldLoadAnalytics?: boolean
shouldRenderOnlyWhenReady?: boolean
/**
* // This option force provider to render children only when isAnalytics is ready
* used with shouldRenderOnlyWhenReady can blocked rendering until consent the first time.
*/
shouldRenderOnlyWhenReady?: boolean
needConsent?: boolean
allowedConsents: CategoryKind[]
deniedConsents: CategoryKind[]
onError?: (err: Error) => void
Expand All @@ -79,18 +79,26 @@
settings,
loadOptions,
shouldRenderOnlyWhenReady = false,
needConsent = true,
onError,
onEventError,
allowedConsents,
deniedConsents,
events,
onLoaded,
}: AnalyticsProviderProps<T>) {
const [isAnalyticsReady, setIsAnalyticsReady] = useState(false)
const [internalAnalytics, setAnalytics] = useState<Analytics | undefined>(
undefined,
)

const shouldLoad = useMemo(() => !!settings?.writeKey, [settings?.writeKey])
const shouldLoad = useMemo(() => {
if (needConsent) {
return false
}

return !!settings?.writeKey
}, [settings?.writeKey, needConsent])

useDeepCompareEffectNoCheck(() => {
if (shouldLoad && settings) {
Expand All @@ -112,6 +120,8 @@
},
})

onLoaded(rudderAnalytics)

setIsAnalyticsReady(true)
},
...loadOptions,
Expand All @@ -119,13 +129,14 @@

analytics.ready(() => {
// @ts-expect-error blabla
setAnalytics({ ...analytics, trackLink: trackLink(analytics) })

Check warning on line 132 in packages/use-analytics/src/analytics/useAnalytics.tsx

View workflow job for this annotation

GitHub Actions / lint

`trackLink` is deprecated. this function is a wrapper of a Track to facilitate the migration from segment to rudderstack
setIsAnalyticsReady(true)
})
} else if (!shouldLoad) {
// When user has refused tracking, set ready anyway
setIsAnalyticsReady(true)
}
// else if (!shouldLoad && !needConsent ) {
// // When user has refused tracking, set ready anyway
// setIsAnalyticsReady(true)
// }
}, [onError, settings, loadOptions, shouldLoad])

const value = useMemo<AnalyticsContextInterface<T>>(() => {
Expand All @@ -144,7 +155,18 @@
}
}, [events, internalAnalytics, isAnalyticsReady, onEventError])

const shouldRender = !shouldRenderOnlyWhenReady || isAnalyticsReady
const shouldRender =
!shouldRenderOnlyWhenReady || (isAnalyticsReady && !needConsent)

useDeepCompareEffectNoCheck(() => {
internalAnalytics?.consent({
consentManagement: {
enabled: true,
allowedConsentIds: allowedConsents,
deniedConsentIds: deniedConsents,
},
})
}, [allowedConsents, deniedConsents])

return (
<AnalyticsContext.Provider value={value}>
Expand Down
7 changes: 2 additions & 5 deletions packages/use-analytics/src/analytics/useDestinations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const transformConfigToDestinations = (
): AnalyticsIntegration[] => {
const { destinations } = config.source

const integrations = destinations.map(
const dest = destinations.map(
({ destinationDefinition, config: { consentManagement } }) => ({
name: destinationDefinition.name,
displayName: destinationDefinition.displayName,
Expand All @@ -23,7 +23,7 @@ const transformConfigToDestinations = (
}),
)

return integrations
return dest
}

/**
Expand Down Expand Up @@ -67,9 +67,6 @@ export const useDestinations = (config: Config) => {
.catch(() => {
setDestinations([])
})
.finally(() => {
setDestinations([])
})
}, [setDestinations, config.analytics])

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,16 @@ import { uniq } from '../helpers/array'
import { IS_CLIENT } from '../helpers/isClient'
import { stringToHash } from '../helpers/misc'
import { isCategoryKind } from '../types'
import type { Config, Consent, Integration, Integrations } from '../types'
import type {
Config,
Consent,
Destination,
Destinations,
EssentialDestination,
} from '../types'

type Context = {
destinations: Integrations
destinations: Destinations
needConsent: boolean
isDestinationsLoaded: boolean
categories: typeof CATEGORIES
Expand All @@ -50,14 +56,16 @@ export const CookieConsentProvider = ({
children,
isConsentRequired,
essentialDestinations,
manualDestinations,
config,
cookiePrefix = COOKIE_PREFIX,
consentMaxAge = CONSENT_MAX_AGE,
consentAdvertisingMaxAge = CONSENT_ADVERTISING_MAX_AGE,
cookiesOptions = COOKIES_OPTIONS,
}: PropsWithChildren<{
isConsentRequired: boolean
essentialDestinations: string[]
essentialDestinations: EssentialDestination[]
manualDestinations?: Destinations
config: Config
cookiePrefix?: string
consentMaxAge?: number
Expand All @@ -74,25 +82,28 @@ export const CookieConsentProvider = ({
isLoaded: isDestinationsLoaded,
} = useDestinations(config)

const destinations: Integrations = useMemo(
const destinations: Destinations = useMemo(
() =>
uniq([
...(analyticsDestinations ?? []).map(
dest =>
({
name: dest.name,
displayName: dest.displayName,
category: dest.consents[0] ?? 'essential',
}) satisfies Integration,
}) satisfies Destination,
),
...essentialDestinations.map(
dest =>
({
name: dest,
name: dest.name,
displayName: dest.displayName,
category: 'essential',
}) satisfies Integration,
}) satisfies Destination,
),
...(manualDestinations ?? []),
]),
[analyticsDestinations, essentialDestinations],
[analyticsDestinations, essentialDestinations, manualDestinations],
)

// We compute a hash with all the integrations that are enabled
Expand All @@ -101,20 +112,17 @@ export const CookieConsentProvider = ({
const destinationsHash = useMemo(
() =>
stringToHash(
uniq([
...destinations.map(({ name }) => name),
...essentialDestinations,
])
uniq(destinations.map(({ name }) => name))
.sort()
.join(undefined),
),
[destinations, essentialDestinations],
[destinations],
)

useEffect(() => {
// We set needConsent at false until we have an answer from segment
// We set needConsent at false until we have an answer from the source
// This is to avoid showing setting needConsent to true only to be set
// to false after receiving segment answer and flicker the UI
// to false after receiving source answer and flicker the UI

setNeedsConsent(
isConsentRequired &&
Expand Down
2 changes: 2 additions & 0 deletions packages/use-analytics/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ export type {
} from './analytics/useAnalytics'
export type {
AnalyticsIntegration,
EssentialDestination,
Destination,
CategoryKind,
Consents,
Consent,
Expand Down
10 changes: 6 additions & 4 deletions packages/use-analytics/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

export type Consents = { consent: CategoryKind }[]

type Destination = {
type RudderDestination = {
id: string
name: string
enabled: boolean
Expand Down Expand Up @@ -41,10 +41,10 @@
id: string
name: string
writeKey: string
config: Record<string, any>

Check warning on line 44 in packages/use-analytics/src/types.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
enabled: boolean
workspaceId: string
destinations: Destination[]
destinations: RudderDestination[]
}
}

Expand All @@ -56,12 +56,14 @@

export type Consent = { [K in CategoryKind]: boolean }

export type Integration = {
export type Destination = {
category: CategoryKind
name: string
displayName: string
}
export type EssentialDestination = Pick<Destination, 'displayName' | 'name'>

export type Integrations = Integration[]
export type Destinations = Destination[]

export type Config = {
analytics?: {
Expand Down
Loading