Skip to content

Commit

Permalink
refactor: align plugins to new structure and integrate in docs
Browse files Browse the repository at this point in the history
  • Loading branch information
axe312ger committed Apr 7, 2021
1 parent 73c016a commit 2f23060
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 13 deletions.
11 changes: 8 additions & 3 deletions packages/docs/src/plugins/client-plugin.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
const { getMatomoTracker } = require('@consent-manager/integration-matomo')
const {
getMatomo,
trackPageViewSPA,
} = require('@consent-manager/integration-matomo')
const { getSegment } = require('@consent-manager/integration-segment')
const {
getGoogleAnalytics,
Expand All @@ -7,11 +10,13 @@ const {
module.exports = (function() {
return {
onRouteUpdate({ location }) {
const { trackPageView } = getMatomoTracker()
const matomo = getMatomo()
const analytics = getSegment()
const ReactGA = getGoogleAnalytics()
window.setTimeout(() => {
trackPageView(location.pathname)
if (matomo) {
trackPageViewSPA({ matomo, location })
}
if (analytics && analytics.page) {
analytics.page()
}
Expand Down
38 changes: 38 additions & 0 deletions packages/docs/src/theme/InitialPageViewTracker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { useEffect } from 'react'

import {
useMatomo,
trackPageViewSPA,
} from '@consent-manager/integration-matomo'
import { useSegment } from '@consent-manager/integration-segment'
import { useGoogleAnalytics } from '@consent-manager/integration-google-analytics'

// Ensure we do this only once per runtime
let trackedMatomo = false
let trackedSegment = false
let trackedGoogleAnalytics = false

export const InitialPageViewTracker = () => {
const { location } = window

const matomo = useMatomo()
useEffect(() => {
if (matomo && !trackedMatomo) {
trackPageViewSPA({ matomo, location })
trackedMatomo = true
}
}, [location, matomo])

const ReactGA = useGoogleAnalytics()
useEffect(() => {
if (ReactGA && ReactGA.pageview && !trackedGoogleAnalytics) {
ReactGA.pageview(location.pathname + location.search)
trackedGoogleAnalytics = true
}
}, [location, ReactGA])

// Segment automatically tracks page view
// @todo how to avoid duplication? some frameworks execute route update hook on initial view, others not (and initial call might not be late enough!)

return null
}
2 changes: 2 additions & 0 deletions packages/docs/src/theme/Root.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import clsx from 'clsx'
import { MDXProvider } from '@mdx-js/react'

import { IntegrationProfile } from '../components/integration-profile'
import { InitialPageViewTracker } from './InitialPageViewTracker'

import { ConsentManager, ConsentManagerForm } from '@consent-manager/core'
import createPersistedState from 'use-persisted-state'
Expand Down Expand Up @@ -70,6 +71,7 @@ function Root({ children }) {
)}
>
{children}
<InitialPageViewTracker />
<ConsentManagerForm
formComponent={InterfaceDefault}
SubmitButton={Button}
Expand Down
18 changes: 18 additions & 0 deletions packages/integration-google-analytics/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
IntegrationConfigOptions,
useDecision,
useIntegration,
locateTracker,
} from '@consent-manager/core'
import React from 'react'

Expand All @@ -23,6 +24,23 @@ export const getGoogleAnalytics = () => {
return window.ReactGA
}

export function useGoogleAnalytics() {
const [isEnabled] = useDecision('google-analytics')
const [tracker, setTracker] = React.useState(null)

React.useEffect(() => {
if (isEnabled && !tracker) {
locateTracker('ReactGA', setTracker)
}
}, [isEnabled, setTracker, tracker])

if (!isEnabled) {
return null
}

return tracker
}

const ScriptInjector: React.FC = () => {
const [isEnabled] = useDecision('google-analytics')
const googleAnalyticsConfig = useIntegration('google-analytics')
Expand Down
2 changes: 2 additions & 0 deletions packages/integration-google-tag-manager/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ export const getGoogleTagManager = () => {
return window.GTM
}

export const useGoogleTagManager = () => React.useMemo(getGoogleTagManager, [])

const ScriptInjector: React.FC = () => {
const [isEnabled] = useDecision('google-tag-manager')
const googleTagManagerConfig = useIntegration('google-tag-manager')
Expand Down
25 changes: 15 additions & 10 deletions packages/integration-matomo/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,30 +37,31 @@ interface TrackedPageData {
}

interface TrackPageViewSPA {
matomo: unknown[]
location: Location
prevLocation?: Location
}

export const trackPageViewSPA = ({
matomo,
location,
prevLocation,
}: TrackPageViewSPA): TrackedPageData | null => {
const paq = window._paq
if (!paq) {
return null
if (!matomo || !location) {
throw new Error(`matomo object and current location are required`)
}
const url = location && location.pathname + location.search + location.hash
const prevUrl =
prevLocation &&
prevLocation.pathname + prevLocation.search + prevLocation.hash
const { title } = document

prevUrl && paq.push(['setReferrerUrl', prevUrl])
paq.push(['setCustomUrl', url])
paq.push(['setDocumentTitle', title])
paq.push(['trackPageView'])
paq.push(['enableLinkTracking'])
paq.push(['trackAllContentImpressions'])
prevUrl && matomo.push(['setReferrerUrl', prevUrl])
matomo.push(['setCustomUrl', url])
matomo.push(['setDocumentTitle', title])
matomo.push(['trackPageView'])
matomo.push(['enableLinkTracking'])
matomo.push(['trackAllContentImpressions'])

return { url, title }
}
Expand Down Expand Up @@ -147,10 +148,14 @@ export function matomoIntegration({
}
}

interface MatomoPrivacyAwareIntegrationArgs extends MatomoIntegrationArgs {
enabledByDefault: boolean
}

export function matomoPrivacyAwareIntegration({
enabledByDefault = true,
...config
}: MatomoIntegrationArgs): IntegrationConfig {
}: MatomoPrivacyAwareIntegrationArgs): IntegrationConfig {
return {
...matomoIntegration(config),
enabledByDefault,
Expand Down
18 changes: 18 additions & 0 deletions packages/integration-segment/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
IntegrationConfigOptions,
useDecision,
useIntegration,
locateTracker,
} from '@consent-manager/core'
import React from 'react'

Expand All @@ -22,6 +23,23 @@ export const getSegment = () => {
return window.analytics || []
}

export function useSegment() {
const [isEnabled] = useDecision('segment')
const [tracker, setTracker] = React.useState(null)

React.useEffect(() => {
if (isEnabled && !tracker) {
locateTracker('analytics', setTracker)
}
}, [isEnabled, setTracker, tracker])

if (!isEnabled) {
return null
}

return tracker
}

const ScriptInjector: React.FC = () => {
const [isEnabled] = useDecision('segment')
const segmentConfig = useIntegration('segment')
Expand Down

0 comments on commit 2f23060

Please sign in to comment.