Using Google AdSense with Gatsby

Gatsby.js is a static site generator that allows deploying content driven sites as a set of HTML files. Gatsby uses React.js as it's default rendering engine, which can be a bit tricky to work with at times.

One of these cases is when embedding Google AdSense code to your templates. There are tutorials and React components on the web on how to get AdSense together. Normally they point you to use lifecycle hooks such as componentDidMount() together with template tweaks. With static deployments this method won't work because the output is static HTML. React is only used when the pages are generated.

By modifying the examples you can easily get to a position, where things seem to be *almost* working, for example resulting in an error WebpackError: window is not defined, and work around it with:

if(type of window != "undefined){
    (window.adsbygoogle = window.adsbygoogle || []).push({});
}

The above code will build without error, but the initialisation will never run and ads won't appear.

Instead of this with Gatsby you'll just need to push out the AdSense boot up code to the end of your template in raw format, using a master template, src/html.js, which contains the main layout of your site. To get started, you can take a copy of the default template from the cache directory like this:

cp .cache/default-html.js src/html.js

Once you have the default template added to your code base, proceed to modify it with your editor. Add the reference to the external AdSense script and the initialisation section before the closing body tag:

<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<script dangerouslySetInnerHTML={{__html: '(window.adsbygoogle = window.adsbygoogle || []).push({});'}}></script>
</body>
</html>

With the above code the page will initialize all AdSense ad units upon code. You'll still need to place the ad units where you want them to. It is ideal to implement as a simple, configurable React.js component. Below is an example of a simple stateless components that you could use as a starting point for yours:

import * as React from "react";

export default ({client, slot, format = 'auto'}) => (
  <div>
  <ins className="adsbygoogle"
  data-ad-client={client}
  data-ad-slot={slot}
  data-ad-format={format}></ins>
  </div>
)

As you can see, the stateless component takes three parameters: client, slot and format. Using the ES6 default values we can define the value for the format to be auto if nothing is defined.

Using this component in anywhere in your Gatsby site, which is templated is straightforward to anyone versed in React. You will need to replace your publisher id and slot id with valid ones you want to use

<GoogleAd client="ca-pub-NNNNNNNNNNNNNNNNN" slot="NNNNNNNNNN" />