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

Add google tagmanager plugin #1123

Merged
merged 11 commits into from
Jun 21, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
14 changes: 14 additions & 0 deletions packages/gatsby-plugin-google-tagmanager/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"presets": [
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why a separate babelrc? Ideally every plugin uses the central one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mindless copy-paste from the google analytics plugin :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ugh, Kyle! Why did you include a babelrc there??

At some point we need to just centrally manage all the npmignore, gitignore, etc. files.

You mind removing both then?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I just remembered that I put it there to fix a bug! Client side code needs it because otherwise it wont work in older browsers. The backticks will end up in the production bundle for example.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think ideally we want (especially) these plugins to export code in a way that the user build process can transpile them together with the user code. I was reading this on the subject recently.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this light I have some new ideas about plugin package structure as well. Because there are standards to distinguish between browser and node parts of a package, I figured that if we can merge the gatsby-ssr and gatsby-node api's in a single entry (since they are both node context), we can use the same technique as other packages use for making the distinction.

You would basically have a main field pointing to the merged gatsby-ssr & gatsby-node entry, and a browser field pointing to the gatsby-browser entry.

Then in the future when webpack supports subfields in esnext you can have esnext.browser point to the raw gatsby-browser code etc. So then plugin packages can export transpiled code and raw code for both contexts at the same time like this:

 "main": "dist/gatsby-node-and-ssr.js",
 "browser: "dist/gatsby-browser.js",
 "esnext": {
      "main": "src/gatsby-node-and-ssr.js",
      "browser": "src/gatsby-browser.js"
 }

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm yeah you're right. That is what we should do. We do after all control the builds so this would be easy to setup. We'd just ship the source code and then users could configure their browserlist according to the needs of their project https://github.com/ai/browserslist

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gatsby-ssr is not a node environment. It's compiled by webpack and can include webpack stuff like importing files etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I see.

["env", {
"targets": {
"browsers": ["last 2 versions", "safari >= 7"]
}
}],
"react"
],
"plugins": [
"transform-object-rest-spread",
"transform-flow-strip-types"
]
}
3 changes: 3 additions & 0 deletions packages/gatsby-plugin-google-tagmanager/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/*.js
!index.js
yarn.lock
34 changes: 34 additions & 0 deletions packages/gatsby-plugin-google-tagmanager/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Logs
logs
*.log

# Runtime data
pids
*.pid
*.seed

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# node-waf configuration
.lock-wscript

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directory
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
node_modules
*.un~
yarn.lock
src
flow-typed
coverage
decls
examples
20 changes: 20 additions & 0 deletions packages/gatsby-plugin-google-tagmanager/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# gatsby-plugin-google-analytics

Easily add Google Tagmanager to your Gatsby site.

## Install
`npm install --save gatsby-plugin-google-tagmanager`

## How to use

```javascript
// In your gatsby-config.js
plugins: [
{
resolve: `gatsby-plugin-google-tagmanager`,
options: {
id: 'YOUR_GOOGLE_TAGMANAGER_ID',
},
},
]
```
1 change: 1 addition & 0 deletions packages/gatsby-plugin-google-tagmanager/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// noop
21 changes: 21 additions & 0 deletions packages/gatsby-plugin-google-tagmanager/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "gatsby-plugin-google-tagmanager",
"description": "Gatsby plugin to add google tagmanager onto a site",
"version": "1.0.0-beta.1",
"author": "Thijs Koerselman <thijs@vauxlab.com>",
"devDependencies": {
"babel-cli": "^6.24.1"
},
"keywords": [
"gatsby",
"gatsby-plugin",
"google analytics",
"google tagmanager"
],
"license": "MIT",
"main": "index.js",
"scripts": {
"build": "babel src --out-dir .",
"watch": "babel -w src --out-dir ."
}
}
38 changes: 38 additions & 0 deletions packages/gatsby-plugin-google-tagmanager/src/gatsby-ssr.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from "react"
import { stripIndent } from "common-tags"

exports.onRenderBody = (
{ setHeadComponents, setPreBodyComponents },
pluginOptions
) => {
if (process.env.NODE_ENV === `production`) {
setHeadComponents([
<script
key="plugin-google-tagmanager"
dangerouslySetInnerHTML={{
__html: stripIndent`
(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer', '${pluginOptions.id}');`,
}}
/>,
])

setPreBodyComponents([
<noscript
key="plugin-google-tagmanager"
dangerouslySetInnerHTML={{
__html: stripIndent`
<iframe
src="https://www.googletagmanager.com/ns.html?id=${pluginOptions.id}"
height="0"
width="0"
style="display: none; visibility: hidden"
/>`,
}}
/>,
])
}
}
6 changes: 6 additions & 0 deletions packages/gatsby/src/cache-dir/api-ssr-docs.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
* @param {function} $0.setHeadComponents Takes an array of components as its
* first argument which are added to the `headComponents` array which is passed
* to the `html.js` component.
* @param {function} $0.setPreBodyComponents Takes an array of components as its
* first argument which are added to the `preBodyComponents` array which is passed
* to the `html.js` component.
* @param {function} $0.setPostBodyComponents Takes an array of components as its
* first argument which are added to the `postBodyComponents` array which is passed
* to the `html.js` component.
Expand Down Expand Up @@ -51,6 +54,9 @@ exports.replaceRenderer = true
* @param {function} $0.setHeadComponents Takes an array of components as its
* first argument which are added to the `headComponents` array which is passed
* to the `html.js` component.
* @param {function} $0.setPreBodyComponents Takes an array of components as its
* first argument which are added to the `preBodyComponents` array which is passed
* to the `html.js` component.
* @param {function} $0.setPostBodyComponents Takes an array of components as its
* first argument which are added to the `postBodyComponents` array which is passed
* to the `html.js` component.
Expand Down
1 change: 1 addition & 0 deletions packages/gatsby/src/cache-dir/default-html.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ module.exports = React.createClass({
{css}
</head>
<body>
{this.props.preBodyComponents}
<div
id="___gatsby"
dangerouslySetInnerHTML={{ __html: this.props.body }}
Expand Down
13 changes: 11 additions & 2 deletions packages/gatsby/src/cache-dir/static-entry.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ module.exports = (locals, callback) => {

let bodyHTML = ``
let headComponents = []
let preBodyComponents = []
let postBodyComponents = []
let bodyProps = {}

Expand All @@ -47,6 +48,10 @@ module.exports = (locals, callback) => {
headComponents = headComponents.concat(components)
}

const setPreBodyComponents = components => {
preBodyComponents = preBodyComponents.concat(components)
}

const setPostBodyComponents = components => {
postBodyComponents = postBodyComponents.concat(components)
}
Expand Down Expand Up @@ -85,6 +90,7 @@ module.exports = (locals, callback) => {
bodyComponent,
replaceBodyHTMLString,
setHeadComponents,
setPreBodyComponents,
setPostBodyComponents,
setBodyProps,
})
Expand All @@ -96,6 +102,7 @@ module.exports = (locals, callback) => {

apiRunner(`onRenderBody`, {
setHeadComponents,
setPreBodyComponents,
setPostBodyComponents,
setBodyProps,
})
Expand Down Expand Up @@ -137,7 +144,7 @@ module.exports = (locals, callback) => {
let fetchedScript = get(stats, fetchKey)

if (!fetchedScript) {
return
return null
}

// If sourcemaps are enabled, then the entry will be an array with
Expand All @@ -147,7 +154,7 @@ module.exports = (locals, callback) => {

// Make sure we found a component.
if (prefixedScript === `/`) {
return
return null
}

return prefixedScript
Expand Down Expand Up @@ -178,10 +185,12 @@ module.exports = (locals, callback) => {
<Html
{...bodyProps}
headComponents={headComponents}
preBodyComponents={preBodyComponents}
postBodyComponents={postBodyComponents}
body={bodyHTML}
path={locals.path}
/>
)}`

callback(null, html)
}
12 changes: 11 additions & 1 deletion packages/gatsby/src/utils/develop.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,22 +103,29 @@ async function startServer(program) {
const apiRunner = require(`${directory}/.cache/api-runner-ssr`)

let headComponents = []
let preBodyComponents = []
let postBodyComponents = []
let bodyProps = {}

const setHeadComponents = components => {
headComponents = headComponents.concat(components)
}

const setPreBodyComponents = components => {
preBodyComponents = preBodyComponents.concat(components)
}

const setPostBodyComponents = components => {
postBodyComponents = postBodyComponents.concat(components)
}

const setBodyProps = props => {
bodyProps = _.merge({}, bodyProps, props)
}

apiRunner(`onRenderBody`, {
setHeadComponents,
setPreBodyComponents,
setPostBodyComponents,
setBodyProps,
})
Expand All @@ -127,6 +134,7 @@ async function startServer(program) {
...bodyProps,
body: ``,
headComponents,
preBodyComponents,
postBodyComponents: postBodyComponents.concat([
<script src="/commons.js" />,
]),
Expand Down Expand Up @@ -185,7 +193,9 @@ async function startServer(program) {
} else {
if (program.open) {
const opn = require(`opn`)
opn(`http://${listener.address().address}:${listener.address().port}`)
opn(
`http://${listener.address().address}:${listener.address().port}`
)
}
const host = listener.address().address === `127.0.0.1`
? `localhost`
Expand Down