Skip to content

Commit

Permalink
Merge pull request #254 from cofacts/name-components-to-track
Browse files Browse the repository at this point in the history
Introduce data-ga and displayName in Google Analytics tracking
  • Loading branch information
MrOrz authored May 20, 2020
2 parents 03e989c + c36969b commit 268b1ed
Show file tree
Hide file tree
Showing 11 changed files with 56 additions and 8 deletions.
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ $ npm run storybook
```
we also use storyshot to do snapshot test with stories, make sure to run:
```
$ npm test -- -u
$ npm test -- -u
```
before pushing to update stories snapshots.
Storybook will be available under /storybook/index.html after build.
Expand All @@ -84,6 +84,14 @@ Also, it will push the following custom variable to `dataLayer`;
- `GA_TRACKING_ID` - see `PUBLIC_GA_TRACKING_ID`
- `CURRENT_USER` - Current user object, set by `useCurrentUser`.

Lastly, in Google Tag Manager we use `data-ga` property to track clicks.
If user clicks a decendant of an React element with `data-ga` property,
a click event will be sent to Google analytics with the written `data-ga`.
(It doesn't even need to be rendered, we [setup the Google Tag Manager](https://github.com/cofacts/rumors-site/pull/254) to read private React instance)

Also, if a component has its `displayName` set,
a click event with that `displayName` is also sent to Google Analytics when any of its decendant is clicked.

## Design and Mockups

* [真的假的 hackfoldr](http://beta.hackfoldr.org/rumors)
Expand Down
4 changes: 3 additions & 1 deletion components/ArticleItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ export default function ArticleItem({
content
)}
{isLink || (
<div className={classes.link}>
<div className={classes.link} data-ga="Bust hoax button">
<Link href="/article/[id]" as={`/article/${article.id}`}>
<a>{t`Bust Hoaxes`}</a>
</Link>
Expand All @@ -162,6 +162,8 @@ export default function ArticleItem({
);
}

ArticleItem.displayName = 'ArticleItem';

ArticleItem.fragments = {
ArticleItem: gql`
fragment ArticleItem on Article {
Expand Down
5 changes: 5 additions & 0 deletions components/ArticlePageLayout.js
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ const FilterGroup = ({
filters: filters.join(','),
})
}
data-ga="Filter(filter)"
/>
)}

Expand Down Expand Up @@ -293,6 +294,7 @@ const FilterGroup = ({
.join(','),
})
}
data-ga="Filter(category)"
/>
)}
</Filters>
Expand Down Expand Up @@ -444,6 +446,7 @@ function ArticlePageLayout({
{lastCursorOfPage !== lastCursor && (
<Box display="flex" pb={1.5} justifyContent="center">
<button
data-ga="LoadMore"
type="button"
className={classes.loadMore}
onClick={() =>
Expand Down Expand Up @@ -481,6 +484,7 @@ function ArticlePageLayout({
<Fab
variant="extended"
aria-label="filters"
data-ga="Mobile filter button"
className={classes.openFilter}
onClick={() => setFiltersShow(!showFilters)}
>
Expand All @@ -502,6 +506,7 @@ function ArticlePageLayout({
<Fade in={showFilters}>
<Box position="relative">
<FilterGroup
data-ga="Mobile filter view"
options={options}
categories={categories}
defaultFilters={defaultFilters}
Expand Down
2 changes: 2 additions & 0 deletions components/ExpandableText.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ const ToggleButton = withStyles({
</button>
));

ToggleButton.displayName = 'ExpandableTextToggleButton';

const ExpandableText = ({ className, lineClamp, wordCount = 40, children }) => {
const [expanded, setExpanded] = useState(false);
const [height, setHeight] = useState(0);
Expand Down
2 changes: 2 additions & 0 deletions components/FeedDisplay.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,4 +103,6 @@ function FeedDisplay({ feedUrl }) {
);
}

FeedDisplay.displayName = 'FeedDisplay';

export default FeedDisplay;
6 changes: 5 additions & 1 deletion components/Filters.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,11 @@ export function Filter({
</div>
{expandable && (
<div className={classes.expand}>
<button type="button" onClick={() => setExpand(e => !e)}>
<button
type="button"
onClick={() => setExpand(e => !e)}
data-ga="FilterExpandButton"
>
{expand ? (
<>
{t`Collapse`}
Expand Down
6 changes: 5 additions & 1 deletion components/ReplyFeedback.js
Original file line number Diff line number Diff line change
Expand Up @@ -291,17 +291,19 @@ function ReplyFeedback({
className={cx(classes.vote, ownVote === 'UPVOTE' && classes.voted)}
type="button"
onClick={e => openVotePopover(e, 'UPVOTE')}
data-ga="Upvote"
>
<ThumbUpIcon className={classes.outlinedIcon} />
</button>
<button
className={cx(classes.vote, ownVote === 'DOWNVOTE' && classes.voted)}
type="button"
onClick={e => openVotePopover(e, 'DOWNVOTE')}
data-ga="Downvote"
>
<ThumbDownIcon className={classes.outlinedIcon} />
</button>
<div className={classes.buttonGroup}>
<div className={classes.buttonGroup} data-ga="Number display">
<button className={classes.vote} type="button">
{positiveFeedbackCount}
<ThumbUpIcon className={classes.icon} />
Expand Down Expand Up @@ -425,6 +427,8 @@ function ReplyFeedback({
);
}

ReplyFeedback.displayName = 'ReplyFeedback';

ReplyFeedback.fragments = {
ArticleReplyFeedbackData,
ArticleReplyFeedbackForUser,
Expand Down
2 changes: 2 additions & 0 deletions components/ReplyItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ function ReplyItem({
);
}

ReplyItem.displayName = 'ReplyItem';

ReplyItem.fragments = {
ReplyItem: gql`
fragment ReplyItem on Reply {
Expand Down
2 changes: 2 additions & 0 deletions components/SortInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,6 @@ function SortInput({ orderBy, onChange = () => {}, options }) {
);
}

SortInput.displayName = 'SortInput';

export default SortInput;
8 changes: 7 additions & 1 deletion components/TimeRange.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,11 @@ function TimeRange({ onChange = () => null, range }) {
onClose={closeMenu}
>
{options.map(option => (
<MenuItem key={option.value} onClick={select(option.value)}>
<MenuItem
key={option.value}
onClick={select(option.value)}
data-ga={`MenuItem(${option.value})`}
>
{option.label}
</MenuItem>
))}
Expand All @@ -190,4 +194,6 @@ function TimeRange({ onChange = () => null, range }) {
);
}

TimeRange.displayName = 'TimeRange';

export default TimeRange;
17 changes: 14 additions & 3 deletions lib/useCurrentUser.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useEffect } from 'react';
import { useLazyQuery } from '@apollo/react-hooks';
import gql from 'graphql-tag';
import { usePushToDataLayer } from './gtm';
import { pushToDataLayer } from './gtm';

export const CurrentUser = gql`
fragment CurrentUser on User {
Expand All @@ -22,10 +22,21 @@ const USER_QUERY = gql`
/**
* Loads currentUser on browser load. Should load from cache first.
*/
let pushDataLayerHandle;
function useCurrentUser() {
const [loadUser, { data }] = useLazyQuery(USER_QUERY);
const [loadUser, { data }] = useLazyQuery(USER_QUERY, {
onCompleted(data) {
// If multiple component with useCurrentUser() is mounted in the same time,
// onCompleted will be invoked multiple times.
//
// We use setTimeout to get rid of duplicated onCompleted calls.
clearTimeout(pushDataLayerHandle);
pushDataLayerHandle = setTimeout(() => {
pushToDataLayer({ CURRENT_USER: data?.GetUser });
}, 10);
},
});
useEffect(() => loadUser(), []);
usePushToDataLayer(data?.GetUser, { CURRENT_USER: data?.GetUser });

return data?.GetUser;
}
Expand Down

0 comments on commit 268b1ed

Please sign in to comment.