diff --git a/packages/gatsby-plugin-google-gtag/README.md b/packages/gatsby-plugin-google-gtag/README.md index 81c8bdfab3e12..6c26b7b26b954 100644 --- a/packages/gatsby-plugin-google-gtag/README.md +++ b/packages/gatsby-plugin-google-gtag/README.md @@ -50,6 +50,8 @@ module.exports = { exclude: ["/preview/**", "/do-not-track/me/too/"], // Defaults to https://www.googletagmanager.com origin: "YOUR_SELF_HOSTED_ORIGIN", + // Delays processing pageview events on route update (in milliseconds) + delayOnRouteUpdate: 0, }, }, }, @@ -137,3 +139,7 @@ If you enable this optional option, Google Global Site Tag will not be loaded at ## The "pluginConfig.exclude" option If you need to exclude any path from the tracking system, you can add it (one or more) to this optional array as glob expressions. + +## The "pluginConfig.delayOnRouteUpdate" option + +If you need to delay processing pageview events on route update (e.g. to wait for page transitions with [`gatsby-plugin-transition-link`](https://www.gatsbyjs.com/plugins/gatsby-plugin-transition-link/)), then this option adds a delay before generating the pageview event. diff --git a/packages/gatsby-plugin-google-gtag/src/gatsby-browser.js b/packages/gatsby-plugin-google-gtag/src/gatsby-browser.js index b99fab185b064..1424b51f20a5a 100644 --- a/packages/gatsby-plugin-google-gtag/src/gatsby-browser.js +++ b/packages/gatsby-plugin-google-gtag/src/gatsby-browser.js @@ -1,8 +1,10 @@ -exports.onRouteUpdate = ({ location }) => { +exports.onRouteUpdate = ({ location }, pluginOptions = {}) => { if (process.env.NODE_ENV !== `production` || typeof gtag !== `function`) { return null } + const pluginConfig = pluginOptions.pluginConfig || {} + const pathIsExcluded = location && typeof window.excludeGtagPaths !== `undefined` && @@ -18,13 +20,15 @@ exports.onRouteUpdate = ({ location }) => { window.gtag(`event`, `page_view`, { page_path: pagePath }) } + const { delayOnRouteUpdate = 0 } = pluginConfig + if (`requestAnimationFrame` in window) { requestAnimationFrame(() => { - requestAnimationFrame(sendPageView) + requestAnimationFrame(() => setTimeout(sendPageView, delayOnRouteUpdate)) }) } else { - // simulate 2 rAF calls - setTimeout(sendPageView, 32) + // Delay by 32ms to simulate 2 requestOnAnimationFrame calls + setTimeout(sendPageView, 32 + delayOnRouteUpdate) } return null