Skip to content

Commit 61507dc

Browse files
committed
feat: content tracking example
1 parent 1fb84dd commit 61507dc

8 files changed

Lines changed: 236 additions & 0 deletions

File tree

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { Box, Button, Paper } from '@mui/material'
2+
import { ElementRef, useEffect, useRef } from 'react'
3+
import { ContentTracking } from '@piwikpro/react-piwik-pro'
4+
5+
export function ContentTrackingMethods() {
6+
const ref = useRef<ElementRef<'div'>>(null)
7+
8+
useEffect(() => {
9+
if (!ref.current) return
10+
11+
ContentTracking.trackContentImpressionsWithinNode(ref.current)
12+
ContentTracking.trackContentInteractionNode(ref.current, 'click')
13+
}, [])
14+
15+
return (
16+
<>
17+
<Paper sx={{ p: 2 }}>
18+
<Box
19+
ref={ref}
20+
data-track-content
21+
data-content-name='element'
22+
data-content-piece='slow element'
23+
>
24+
Track content within a specific dom node
25+
</Box>
26+
</Paper>
27+
28+
<Box sx={{ my: 5 }}>
29+
<Button
30+
variant='outlined'
31+
onClick={() =>
32+
ContentTracking.trackContentImpression(
33+
'tracking element',
34+
'button',
35+
'button'
36+
)
37+
}
38+
>
39+
Manual content tracking on demand
40+
</Button>
41+
</Box>
42+
</>
43+
)
44+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import Box from '@mui/material/Box'
2+
import Tab from '@mui/material/Tab'
3+
import Tabs from '@mui/material/Tabs'
4+
import { useState } from 'react'
5+
import { Login } from './Login'
6+
import { Register } from './Register'
7+
8+
interface TabPanelProps {
9+
children?: React.ReactNode
10+
index: number
11+
value: number
12+
}
13+
14+
function CustomTabPanel(props: TabPanelProps) {
15+
const { children, value, index, ...other } = props
16+
17+
return (
18+
<div
19+
role='tabpanel'
20+
hidden={value !== index}
21+
id={`simple-tabpanel-${index}`}
22+
aria-labelledby={`simple-tab-${index}`}
23+
{...other}
24+
>
25+
{value === index && <Box sx={{ p: 3 }}>{children}</Box>}
26+
</div>
27+
)
28+
}
29+
30+
export function ContentTrackingForm() {
31+
const [value, setValue] = useState(0)
32+
33+
const handleChange = (_event: React.SyntheticEvent, newValue: number) => {
34+
setValue(newValue)
35+
}
36+
37+
return (
38+
<Box sx={{ width: '100%', maxWidth: '750px' }}>
39+
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
40+
<Tabs
41+
value={value}
42+
onChange={handleChange}
43+
aria-label='basic tabs example'
44+
>
45+
<Tab label='Login' />
46+
<Tab label='Register' />
47+
</Tabs>
48+
</Box>
49+
<CustomTabPanel value={value} index={0}>
50+
<Login />
51+
</CustomTabPanel>
52+
<CustomTabPanel value={value} index={1}>
53+
<Register />
54+
</CustomTabPanel>
55+
</Box>
56+
)
57+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { Button, Stack, TextField } from '@mui/material'
2+
import { useEffect } from 'react'
3+
import { ContentTracking } from '@piwikpro/react-piwik-pro'
4+
5+
export function Login() {
6+
// NOTE: candidate for a custom hook useTrackAllContentImpressions()
7+
useEffect(() => {
8+
ContentTracking.trackAllContentImpressions()
9+
10+
return () => ContentTracking.clearTrackedContentImpressions()
11+
}, [])
12+
13+
return (
14+
<Stack gap={2} data-track-content data-content-name='Login form'>
15+
<TextField label='Login' data-content-piece='Login input' />
16+
<TextField label='Password' data-content-piece='Password input' />
17+
<Button variant='contained' data-content-piece='Login button'>
18+
Login
19+
</Button>
20+
</Stack>
21+
)
22+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { Button, Stack, TextField } from '@mui/material'
2+
import { ContentTracking } from '@piwikpro/react-piwik-pro'
3+
import { useEffect } from 'react'
4+
5+
export function Register() {
6+
useEffect(() => {
7+
ContentTracking.trackAllContentImpressions()
8+
9+
return () => ContentTracking.clearTrackedContentImpressions()
10+
}, [])
11+
12+
return (
13+
<Stack gap={2} data-track-content data-content-name='Register form'>
14+
<TextField label='Login' data-content-piece='Login input' />
15+
<TextField type='email' label='Email' data-content-piece='Email input' />
16+
<TextField
17+
type='password'
18+
label='Password'
19+
data-content-piece='Password input'
20+
/>
21+
<TextField
22+
type='password'
23+
label='Confirm Password'
24+
data-content-piece='Confirm password input'
25+
/>
26+
<Button variant='contained' data-content-piece='Register button'>
27+
Register
28+
</Button>
29+
</Stack>
30+
)
31+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import { Box, CircularProgress } from '@mui/material'
2+
import Paper from '@mui/material/Paper'
3+
import Typography from '@mui/material/Typography'
4+
import { FunctionComponent, useEffect, useState } from 'react'
5+
import { ContentTrackingMethods } from '../components/ContentTracking/ContentTrackingMethods'
6+
import { ContentTrackingForm } from '../components/ContentTrackingForm/ContentTrackingForm'
7+
8+
const ContentTrackingPage: FunctionComponent = () => {
9+
const [isLoading, setIsLoading] = useState(true)
10+
11+
useEffect(() => {
12+
document.title = 'Content Tracking'
13+
}, [])
14+
15+
useEffect(() => {
16+
const timeout = setTimeout(() => {
17+
setIsLoading(false)
18+
}, 3000)
19+
20+
return () => {
21+
clearTimeout(timeout)
22+
}
23+
}, [])
24+
25+
return (
26+
<Paper
27+
sx={{
28+
p: 2,
29+
display: 'flex',
30+
flexDirection: 'column'
31+
}}
32+
>
33+
<Typography component='h1' variant='h4' align='center'>
34+
Content Tracking Example
35+
</Typography>
36+
37+
<Box>
38+
<Paper sx={{ p: 5, mt: 5 }}>
39+
<Typography
40+
data-track-content
41+
data-content-name='block'
42+
data-content-piece='paragraph'
43+
data-content-target='target'
44+
>
45+
This element will be tracked automatically if it's present in DOM
46+
before tracking script is loaded and `Interactions with popups and
47+
content` setting is turned on in the administration panel
48+
</Typography>
49+
</Paper>
50+
51+
<Paper sx={{ mt: 5, p: 3 }}>
52+
<Typography>
53+
For content that will appear later in the DOM, like modals or
54+
components that are waiting for data to be loaded, use{' '}
55+
<b>ContentTracking</b> module
56+
</Typography>
57+
58+
<Box sx={{ py: 5 }}>
59+
{isLoading ? <CircularProgress /> : <ContentTrackingMethods />}
60+
</Box>
61+
</Paper>
62+
63+
<Paper sx={{ mt: 3 }}>
64+
<ContentTrackingForm />
65+
</Paper>
66+
</Box>
67+
</Paper>
68+
)
69+
}
70+
71+
export default ContentTrackingPage

example/src/routes.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import HomePage from './pages/HomePage.tsx'
22
import ECommercePage from './pages/ECommercePage.tsx'
33
import CustomEventPage from './pages/CustomEventPage.tsx'
44
import GoalConversionsPage from './pages/GoalConversionsPage.tsx'
5+
import ContentTrackingPage from './pages/ContentTrackingPage.tsx'
56

67
export const routes = [
78
{
@@ -23,5 +24,10 @@ export const routes = [
2324
path: '/goal-conversions',
2425
name: 'Goal Conversions',
2526
element: <GoalConversionsPage />
27+
},
28+
{
29+
path: '/content-tracking',
30+
name: 'Content Tracking',
31+
element: <ContentTrackingPage />
2632
}
2733
]

src/constants/track-event.constant.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export enum TRACK_EVENT {
2727
LOG_ALL_CONTENT_BLOCKS_ON_PAGE = 'logAllContentBlocksOnPage',
2828
CONTENT_INTERACTION_NODE = 'trackContentInteractionNode',
2929
CONTENT_INTERACTION = 'trackContentInteraction',
30+
CLEAR_TRACKED_CONTENT_IMPRESSIONS = 'clearTrackedContentImpressions',
3031
LINK = 'trackLink',
3132
ENABLE_LINK_TRACKING = 'enableLinkTracking',
3233
SET_IGNORE_CLASSES = 'setIgnoreClasses',

src/services/content-tracking/contentTracking.service.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,7 @@ export function trackContentInteraction(contentInteraction: string, contentName:
5252
contentTarget
5353
]);
5454
}
55+
56+
export function clearTrackedContentImpressions(){
57+
PaqService.push([TRACK_EVENT.CLEAR_TRACKED_CONTENT_IMPRESSIONS])
58+
}

0 commit comments

Comments
 (0)