gatsbyjs / gatsby

The best React-based framework with performance, scalability and security built in.
https://www.gatsbyjs.com
MIT License
55.21k stars 10.33k forks source link

[gatsby-plugin-google-analytics] Possible bug with `anonymize: false` option #6902

Closed yom-ko closed 6 years ago

yom-ko commented 6 years ago

Description

In gatsby-config.js, in the plugin options, when anonymize option is explicitly set to false, ie:

// Setting this parameter is optional
        anonymize: false,

the following code is added to the bundled analytics snippet:

ga('set', 'anonymizeIp', 1);

I guess, in this case, there should not be any code setting the anonymizeIp feature at all in the bundled snippet. Moreover, as far as I know, the 1 value can be potentially interpreted as true, which would enable the IP anonymization (instead of disabling it).

Steps to reproduce

  1. Install gatsby-plugin-google-analytics (version 2.0.0-beta.3)
  2. In gatsby-config.js, in the plugin options, add anonymize: false
  3. Build the project with gatsby build / yarn build command.
  4. Open the site in a web-browser and inspect the page source code.

Expected result

The source code would have the GA snippet with no mention of the anonymizeIp feature.

Actual result

The source code will have the GA snippet with ga('set', 'anonymizeIp', 1); statement.

Environment

System: OS: Windows 10 CPU: x64 Intel(R) Core(TM) i5 CPU M 560 @ 2.67GHz Binaries: Yarn: 1.7.0 - C:\Program Files (x86)\Yarn\bin\yarn.CMD npm: 6.1.0 - C:\Program Files\nodejs\npm.CMD

File contents (if changed)

gatsby-config.js:

const {
  NODE_ENV,
  URL: NETLIFY_SITE_URL = '<URL>',
  DEPLOY_PRIME_URL: NETLIFY_DEPLOY_URL = NETLIFY_SITE_URL,
  CONTEXT: NETLIFY_ENV = NODE_ENV
} = process.env;
const isNetlifyProduction = NETLIFY_ENV === 'production';
const siteUrl = isNetlifyProduction ? NETLIFY_SITE_URL : NETLIFY_DEPLOY_URL;

module.exports = {
  siteMetadata: {
    siteUrl
  },
  plugins: [
    {
      resolve: 'gatsby-plugin-google-analytics',
      options: {
        trackingId: '<ID>',
        // Puts tracking script in the head instead of the body
        head: false,
        // Setting this parameter is optional
        anonymize: false,
        // Avoids sending pageview hits from custom paths
        exclude: ['/preview/**']
      }
    },
    'gatsby-plugin-react-helmet',
    {
      resolve: 'gatsby-plugin-manifest',
      options: {
        name: '<name>',
        short_name: '<short_name>',
        description: '<description>',
        dir: 'ltr',
        lang: 'en-US',
        start_url: '/',
        display: 'standalone',
        theme_color: '#000',
        background_color: '#fff',
        orientation: 'portrait-primary',
        icon: 'src/favicon.png'
      }
    },
    'gatsby-plugin-offline',
    'gatsby-plugin-sitemap',
    {
      resolve: 'gatsby-plugin-robots-txt',
      options: {
        resolveEnv: () => NETLIFY_ENV,
        env: {
          production: {
            policy: [{ userAgent: '*', disallow: ['/'] }]
          },
          'branch-deploy': {
            policy: [{ userAgent: '*', disallow: ['/'] }],
            sitemap: null,
            host: null
          },
          'deploy-preview': {
            policy: [{ userAgent: '*', disallow: ['/'] }],
            sitemap: null,
            host: null
          }
        }
      }
    },
    'gatsby-plugin-sass',
    {
      resolve: 'gatsby-plugin-emotion',
      options: {
        // Any babel-plugin-emotion options
      }
    },
    {
      resolve: 'gatsby-source-filesystem',
      options: {
        name: 'blog',
        path: `${__dirname}/src/blog/`
      }
    },
    {
      resolve: 'gatsby-source-filesystem',
      options: {
        name: 'data',
        path: `${__dirname}/src/data/`
      }
    },
    'gatsby-transformer-sharp',
    'gatsby-plugin-sharp',
    {
      resolve: 'gatsby-transformer-remark',
      options: {
        plugins: [
          {
            resolve: 'gatsby-remark-images',
            options: {
              // It's important to specify the maxWidth (in pixels) of
              // the content container as this plugin uses this as the
              // base for generating different widths of each image.
              maxWidth: 960
            }
          },
          {
            resolve: 'gatsby-remark-copy-linked-files',
            options: {
              destinationDir: 'static'
            }
          }
        ]
      }
    },
    'gatsby-plugin-netlify'
  ]
};

package.json:

{
  "name": "<name>",
  "version": "1.0.0",
  "license": "MIT",
  "private": true,
  "dependencies": {
    "bulma": "^0.7.1",
    "emotion": "^9.2.6",
    "emotion-server": "^9.2.6",
    "gatsby": "^2.0.0-beta.61",
    "gatsby-image": "^2.0.0-beta.7",
    "gatsby-plugin-emotion": "^2.0.0-beta.3",
    "gatsby-plugin-google-analytics": "^2.0.0-beta.3",
    "gatsby-plugin-manifest": "^2.0.2-beta.3",
    "gatsby-plugin-netlify": "^2.0.0-beta.4",
    "gatsby-plugin-offline": "^2.0.0-beta.5",
    "gatsby-plugin-react-helmet": "^2.0.11",
    "gatsby-plugin-robots-txt": "^1.2.0",
    "gatsby-plugin-sass": "^2.0.0-beta.6",
    "gatsby-plugin-sharp": "^2.0.0-beta.7",
    "gatsby-plugin-sitemap": "^2.0.0-beta.3",
    "gatsby-remark-copy-linked-files": "^2.0.0-beta.3",
    "gatsby-remark-images": "^2.0.1-beta.9",
    "gatsby-source-filesystem": "^2.0.1-beta.10",
    "gatsby-transformer-remark": "^2.1.1-beta.5",
    "gatsby-transformer-sharp": "^2.1.1-beta.6",
    "node-sass": "^4.9.2",
    "react": "^16.4.1",
    "react-dom": "^16.4.1",
    "react-emotion": "^9.2.6",
    "react-helmet": "^5.2.0",
    "rehype-react": "^3.0.3"
  },
  "devDependencies": {
    "eslint": "^5.2.0",
    "eslint-config-airbnb": "^17.0.0",
    "eslint-plugin-import": "^2.13.0",
    "eslint-plugin-jsx-a11y": "^6.1.1",
    "eslint-plugin-react": "^7.10.0",
    "prettier": "^1.14.0",
    "prettier-eslint": "^8.8.2"
  },
  "scripts": {
    "dev": "gatsby develop",
    "build": "gatsby build"
  }
}

gatsby-node.js:

/**
 * Implement Gatsby's Node APIs in this file.
 *
 * See: https://www.gatsbyjs.org/docs/node-apis/
 */

const path = require('path');

exports.createPages = ({ actions, graphql }) => {
  const { createPage } = actions;

  const blogPostTemplate = path.resolve('src/templates/blogPostTemplate.js');

  return graphql(`
    {
      allMarkdownRemark(sort: { order: DESC, fields: [frontmatter___date] }, limit: 1000) {
        edges {
          node {
            frontmatter {
              path
            }
          }
        }
      }
    }
  `).then((result) => {
    if (result.errors) {
      return Promise.reject(result.errors);
    }

    return result.data.allMarkdownRemark.edges.forEach(({ node }) => {
      createPage({
        path: node.frontmatter.path,
        component: blogPostTemplate,
        context: {} // additional data can be passed via context
      });
    });
  });
};

gatsby-browser.js: N/A gatsby-ssr.js: N/A

Chuloo commented 6 years ago

While looking through the GA docs on IP Anonymization the bundled output when 'anonymizeIp': true should be ga('set', 'anonymizeIp', true).

After looking through with @m-allanson, the bug looks most likely in: https://github.com/gatsbyjs/gatsby/blob/bf3208ddc02c240302fff5b112343d715c69a0ca/packages/gatsby-plugin-google-analytics/src/gatsby-ssr.js#L47-L53 Placing more emphasis on the condition and return statements in the ternary operator.

Could you send in a PR @yom-ko ?

yom-ko commented 6 years ago

Sorry for the late response. Yeah, I will try to make and send a proper PR.