Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(gatsby-plugin-google-analytics): add custom event helper #17612

Merged
merged 29 commits into from
Nov 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
8040a0f
Added CustomTrackingEvent function
robmarshall Sep 13, 2019
921d8de
Removed console log
robmarshall Sep 13, 2019
a7292a8
Documentation on how to use function
robmarshall Sep 13, 2019
50c4e4e
Added basic test
robmarshall Sep 13, 2019
4218195
Update packages/gatsby-plugin-google-analytics/src/index.js
robmarshall Sep 16, 2019
dd42808
Update packages/gatsby-plugin-google-analytics/src/index.js
robmarshall Sep 16, 2019
338fb63
Update packages/gatsby-plugin-google-analytics/src/index.js
robmarshall Sep 16, 2019
b6b2e50
Removed spaces
robmarshall Sep 16, 2019
a63ae89
Update packages/gatsby-plugin-google-analytics/README.md
robmarshall Sep 16, 2019
640c633
Update packages/gatsby-plugin-google-analytics/src/index.js
robmarshall Sep 17, 2019
a55bcb4
Update packages/gatsby-plugin-google-analytics/src/index.js
robmarshall Sep 17, 2019
20a692c
Update packages/gatsby-plugin-google-analytics/README.md
robmarshall Sep 17, 2019
2d33997
Removed proptypes as function not a component
robmarshall Sep 17, 2019
b61a248
Added target and nonInteraction values
robmarshall Sep 17, 2019
65a3b8f
Added hitCallback to customTracker
robmarshall Sep 17, 2019
b95bc58
Updated readme with new customTracker details
robmarshall Sep 17, 2019
f3dc978
Updated value to "integer" rather than number
robmarshall Sep 17, 2019
0d6809f
Update packages/gatsby-plugin-google-analytics/src/index.js
robmarshall Sep 18, 2019
1ec34bf
Added createFunctionWithTimeout
robmarshall Sep 18, 2019
841ff0b
Corrected function export
robmarshall Sep 18, 2019
766a2dd
Added hitCallback timeout explaination
robmarshall Sep 18, 2019
f0b2d70
Update packages/gatsby-plugin-google-analytics/src/__tests__/index.js
robmarshall Sep 18, 2019
722e14b
Update packages/gatsby-plugin-google-analytics/src/__tests__/index.js
robmarshall Sep 18, 2019
e252b04
Update packages/gatsby-plugin-google-analytics/README.md
robmarshall Oct 11, 2019
8d21fc5
Update packages/gatsby-plugin-google-analytics/src/__tests__/index.js
robmarshall Oct 11, 2019
7d7ee6c
Update packages/gatsby-plugin-google-analytics/README.md
robmarshall Oct 11, 2019
5f3ca68
Update packages/gatsby-plugin-google-analytics/README.md
robmarshall Oct 11, 2019
6230f86
cleanup code & fix typedefs
wardpeet Nov 13, 2019
2d1bd25
Merge branch 'master' into topics/custom-analytics-events
wardpeet Nov 13, 2019
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
52 changes: 52 additions & 0 deletions packages/gatsby-plugin-google-analytics/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,58 @@ This plugin also supports several optional General fields documented in [Google

These fields can be specified in the plugin's `options` as shown in the [How to use](#how-to-use) section.

## TrackCustomEvent Function

To allow custom events to be tracked, the plugin exposes a function to include in your project.

To use it, import the package and call the event within your components and business logic.

```jsx
import React
import { trackCustomEvent } from 'gatsby-plugin-google-analytics'

export default () => {
<div>
<button
onClick={e => {
// To stop the page reloading
e.preventDefault()
// Lets track that custom click
trackCustomEvent({
// string - required - The object that was interacted with (e.g.video)
category: "Special Button",
// string - required - Type of interaction (e.g. 'play')
action: "Click",
// string - optional - Useful for categorizing events (e.g. 'Spring Campaign')
label: "Gatsby Plugin Example Campaign",
// number - optional - Numeric value associated with the event. (e.g. A product ID)
value: 43
})
//... Other logic here
}}
>
Tap that!
</button>
</div>
}
```

### All Fields Options

- `category`: string - required
- `action`: string - required
- `label`: string
- `value`: integer
- `nonInteraction`: bool
- `transport`: string
- `hitCallback`: function
robmarshall marked this conversation as resolved.
Show resolved Hide resolved

For more information see the [Google Analytics](https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#events) documentation.

#### hitCallback

A timeout is included by default incase the Analytics library fails to load. For more information see [Google Analytics - Handling Timeouts](https://developers.google.com/analytics/devguides/collection/analyticsjs/sending-hits#handling_timeouts)

## Troubleshooting

### No actions are tracked
Expand Down
13 changes: 13 additions & 0 deletions packages/gatsby-plugin-google-analytics/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,16 @@ export class OutboundLink extends React.Component<
OutboundLinkProps & React.HTMLProps<HTMLAnchorElement>,
any
> {}

export interface CustomEventArgs {
category: string
action: string
label?: string
value?: string
nonInteraction: boolean
transport: "beacon" | "xhr" | "image"
hitCallback: Function
callbackTimeout: Number
}

export function trackCustomEvent(args: CustomEventArgs): void
3 changes: 2 additions & 1 deletion packages/gatsby-plugin-google-analytics/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,6 @@
},
"engines": {
"node": ">=8.0.0"
}
},
"types": "./index.d.ts"
}
38 changes: 37 additions & 1 deletion packages/gatsby-plugin-google-analytics/src/__tests__/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from "react"
import { cleanup, fireEvent, render } from "@testing-library/react"
import { OutboundLink } from "../"
import { trackCustomEvent, OutboundLink } from "../"

describe(`index.js`, () => {
describe(`<OutboundLink />`, () => {
Expand Down Expand Up @@ -65,4 +65,40 @@ describe(`index.js`, () => {
expect(props.onClick).toHaveBeenCalled()
})
})

describe(`trackCustomEvent()`, () => {
afterEach(cleanup)

const setup = props => {
const utils = render(
<button
onClick={e => {
e.preventDefault()
trackCustomEvent({
category: `event`,
action: `action`,
label: `label`,
value: `value`,
})
}}
>
tapthis
</button>
)

return Object.assign({}, utils, {
button: utils.getByText(`tapthis`),
})
}

it(`sends tracking event when clicked`, () => {
window.ga = jest.fn()

const { button } = setup()

fireEvent.click(button)

expect(window.ga).toHaveBeenCalled()
})
})
})
51 changes: 50 additions & 1 deletion packages/gatsby-plugin-google-analytics/src/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
import React from "react"
import PropTypes from "prop-types"

const createFunctionWithTimeout = (callback, opt_timeout = 1000) => {
let called = false
const raceCallback = () => {
if (!called) {
called = true
callback()
}
}
setTimeout(raceCallback, opt_timeout)
return raceCallback
}

function OutboundLink(props) {
return (
<a
Expand Down Expand Up @@ -53,4 +65,41 @@ OutboundLink.propTypes = {
onClick: PropTypes.func,
}

export { OutboundLink }
/**
* This allows the user to create custom events within their Gatsby projects.
*
* @param {import('gatsby-plugin-google-analytics').CustomEventArgs} args
* @see https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#events
*/
function trackCustomEvent({
category,
action,
label,
value,
nonInteraction = true,
transport,
hitCallback,
callbackTimeout = 1000,
}) {
if (typeof window !== `undefined` && window.ga) {
const trackingEventOptions = {
eventCategory: category,
eventAction: action,
eventLabel: label,
eventValue: value,
nonInteraction: nonInteraction,
transport,
}

if (hitCallback && typeof hitCallback === `function`) {
trackingEventOptions.hitCallback = createFunctionWithTimeout(
hitCallback,
callbackTimeout
)
}

window.ga(`send`, `event`, trackingEventOptions)
}
}
robmarshall marked this conversation as resolved.
Show resolved Hide resolved

export { OutboundLink, trackCustomEvent }