Skip to content

Commit

Permalink
feat(gatsby-plugin-google-analytics): add custom event helper (#17612)
Browse files Browse the repository at this point in the history
  • Loading branch information
robmarshall authored and wardpeet committed Nov 13, 2019
1 parent 4db2ff1 commit 4e431f3
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 3 deletions.
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

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)
}
}

export { OutboundLink, trackCustomEvent }

0 comments on commit 4e431f3

Please sign in to comment.