How and why I added AdSense and an AdBlock detector to my personal website
This article describes how I added AdSense to my personal website and how I request that site visitors pause AdBlock while reading my blog
If you are reading this article on briancaffey.github.io/2021/10/31/how-and-why-i-added-adsense-and-adblock-detector-to-my-website, then you will be prompted to pause your ad blocker if you are using one. If you are not using an ad blocker, I recommend that you consider installing one. Reading this article on a browser with AdBlock enabled will allow you to see how I detect AdBlock and ask people to pause it when they are on my site.
This article is a deep dive on how I added ads to my site with Google AdSense and how I request that visitors to my site pause AdBlock so that I can make more money from Google AdSense.
How I added AdSense to my site
I have been enjoying using my GitHub Pages website to learn more about static sites, JAMStack and Nuxt.js, an awesome Vue.js framework with support for building statically generated sites. I have been able to learn and implement several different features which I have written about on my blog. Some examples include:
Adding a Drift chat window so users can message me directly- Implementing a contact form with formsubmit.io
Using Vue.js components in Markdown files to add interactive elements to my articles (such as graphs)
Adding a custom MailChimp newsletter sign-up form that is included in the footer of each page of my blog
Adding an RSS feed for my blog- Adding a site index and submitting it to Google
I have also been learning the suite of Google tools for monitoring and measuring traffic to my site, including Google Analytics and Google Search Console. Google Search Console is helpful for understanding the search terms that people are using when searching Google that result in organic traffic to my site.
At one point I found out that another website was using the same Google Tracking code that I had previously hard-coded into an old version of my website, and my Google Analytics started measuring traffic to URLs that I didn't recognize as belonging to my site. I was able to fix this by adding a Hostname filter rule in Google Analytics.
One area that I have not had any experience with until recently is Google AdSense. Google AdSense allows you to place ads on your website. Here's an overview of what I did to get started:
Add a site in Google AdSense- Submit my site for approval (this takes a few days)
Install and configure the Google AdSense plugin for NuxtJS
Add the `ads.txt` file generated by Google AdSense to my site
Confirm my address by entering a code that was mailed to me
Connect a bank account to my Google AdSense account
Here's the address confirmation code that I received from Google:
Here's the config code for AdSense from `nuxt.config.js`:
/*
** Nuxt.js modules
*/
modules: [
// Doc: https://axios.nuxtjs.org/usage
'@nuxtjs/axios',
// Doc: https://github.com/nuxt/content
'@nuxt/content',
// Doc: https://www.npmjs.com/package/@nuxtjs/sitemap
'@nuxtjs/sitemap',
'@nuxtjs/feed',
'nuxt-i18n',
['@nuxtjs/google-adsense', { <-- AdSense config
id: 'ca-pub-4924597640144289'
}]
],
The process was pretty simple. Google now automatically places ads on my site in a few different formats:
ads displayed on the top and bottom of the page
popup ads displayed between route navigation
ads automatically inserted into the body of the page between paragraphs in my articles
ads that I place on articles explicitly using the `<adsbygoogle />` Vue component
When everything was set up properly I started seeing ads on my site, and I see a non-zero value in my estimated earnings in the AdSense console. Google has a payment threshold of $100, so I need make this amount before I can start receiving money from Google.
My estimated earning report shows that I make between $0 and $4.32 in ad sales per day. I'm interested to see how much I can make with an article that I post across the many different channels that I can publish to. I explored this in a previous article, but the main channels I can use for sharing content are:
DEV.to
Facebook
Hashnode
Medium
Reddit
Discord
Hacker Noon
Twitter
My MailChimp mailing list
Substack
Hacker News
This article should be a good place to start exploring how effective the different channels are in driving content to my site, and I'll update this article later with more details and numbers from my AdSense reports.
How I built an AdBlock detector for my site
I assume that most people reading my blog have an AdBlock extension installed in their browser like I do, such as AdBlock or ABP (AdBlock Pro). This got me thinking about how I could implement a simple AdBlock detector for my site that would hide the contents of the page if AdBlock is enabled.
How do you check to see if AdBlock is enabled?
I started with this question, and I came across this StackOverflow question which inspired the code that I am now using on this site to detect AdBlock.
The components of my AdBlock detector
There are a few different parts of my Nuxt Application that work together to detect if AdBlock is active and request that the user pause AdBlock for the site. The main components are:
A component called `AdBlockBlocker` - This component is used in the default layout, so it is included in all pages on briancaffey.github.io
Vuex store module called `adblock` - this module is used to keep track of a boolean value that indicates if AdBlock is enabled - the module also has a simple getter and a mutation for turning adBlock to true or false
Some logic in the `default.vue` layout that is used for almost all of the pages on my site - the getter from the Vuex store is used here to either show regular content or a message that the user needs to pause AdBlock
A component/page to display when AdBlock is enabled - this component asks the user to please pause AdBlock - I named this component `PleaseDisableAdblock.vue`
localStorage - this is used to keep track of the presence of an AdBlocker that is blocking ads
Here's an overview of each part:
AdBlockBlocker.vue
This is the key part of how the AdBlock detection works. If the client is unable to download the `adsbygoogle.js` file, then that indicates that the user is using AdBlock.
<template>
<div />
</template>
<script>
export default {
mounted () {
// if adblock is detected through a value that is set local storage, then show the AdBlock message
// the `adblockEnabled` value is set in the catch block of the `detectAdBlock` method
// (see adblock/setAdblockEnabled mutation)
if (JSON.parse(localStorage.getItem('adblockEnabled')) === true) {
this.$store.commit('adblock/setAdblockEnabled', true)
}
// check to see if the URL can be accessed on a 5 second interval
setInterval(() => {
this.detectAdBlock()
}, 5000)
},
methods: {
async detectAdBlock () {
// this is a URL that should be blocked by AdBlock
const googleAdUrl = 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js'
// make a request to the above URL
await fetch(new Request(googleAdUrl)).then((_) => {
// isAdblockEnabled is false by default
// Check to see if isAblockEnabled was set to true by a previous request
if (this.$store.getters['adblock/isAdblockEnabled'] === true) {
// if the request was successful, then the user does not have AdBlock enabled,
// so we can set isAdblockEnabled to false using the setAdblockEnabled mutation
// this mutation will also set the `adblockEnabled` value in local storage to "false"
// `adblockEnabled` be `JSON.parse`d since it is saved in localStorage as a string
this.$store.commit('adblock/setAdblockEnabled', false)
window.localStorage.setItem('adblockEnabled', 'false')
// do a full reload of the page
window.location.reload()
}
}).catch((_) => {
// if the request was unsuccessful, then the user has AdBlock enabled.
// we can set isAdblockEnabled to true using the setAdblockEnabled mutation
// this will also set the `adblockEnabled` value in local storage to "true"
this.$store.commit('adblock/setAdblockEnabled', true)
window.localStorage.setItem('adblockEnabled', 'true')
})
}
}
}
</script>
One other important point about this component is that it runs AdBlock detection using `setInterval`, meaning that it will check if AdBlock is enabled every few seconds while a user is on my site.
If AdBlock is enabled, the request will fail and the Vuex store value will be updated, which will cause the site to display the `PleaseDisableAdblock.vue` component.
If AdBlock is not enabled, then the file will be read from disk cache and the Vuex store value will remain `false`.
Vuex Store
This is a very simple Vuex store module. The `isAdblockEnabled` getter will be used in the `default.vue` layout to component.
let initialValue = false
if (process.window) {
initialValue = JSON.parse(window.localStorage.getItem('adblockEnabled')) || false
}
export const state = () => ({
adblockEnabled: initialValue
})
export const getters = {
isAdblockEnabled: state => state.adblockEnabled
}
export const mutations = {
setAdblockEnabled (state, payload) {
state.adblockEnabled = payload
}
}
default.vue layout logic
<template>
<div>
<Navigation />
<PleaseDisableAdblock v-if="$store.getters['adblock/isAdblockEnabled']" />
<Nuxt v-else />
<AdBlockerBlocker />
<Footer />
</div>
</template>
Content to show to request that a user pauses AdBlock
When users has AdBlock enabled, I show a simple message that asks them to please disable AdBlock. I also want to invite people who do not wish to disabled AdBlock to read my blog directly on GitHub, or to read it without ads by cloning or forking my repo, building it and running it in development mode with `yarn dev`.
Why am I adding ads and an AdBlock detector to my site?
Being asked to pause AdBlock is increasingly common. I have noticed that the experience is not the same on each site that requests AdBlock be paused. For example:
a site might ask you to pause AdBlock, but you have the option to continue without pausing AdBlock
a site shows you a preview of an article and asks you to unpause AdBlock to see the full article
all site content is hidden if you are using AdBlock, and a pop-up message ask you to "Continue to site" once you have paused AdBlock.
I remember being able to delete AdBlock detection modals and backgrounds on some sites as a way of getting around ad block detectors. This is as easy as Cmd + Shift + C, click on the element that is blocking the page content and `delete` the selected element.
One of the reasons I wanted to implement AdBlock detection is to see what is possible from the perspective of user experience (UX). Ideally, here's how I want to the "please disable AdBlock" experience to work on my site:
A user visits my site with AdBlock enabled1. For a few seconds, the user can start reading the content of the article
The page content is replaced with a message that says "Please disable AdBlock" and some other links that people may find interesting or helpful.
The user goes into the AdBlock extension and pauses AdBlock on my site1. The original page content is then displayed with ads
If the user re-enables AdBlock shortly after pausing it, then the "Please disable AdBlock" message should be displayed again.
I don't want to ask the user to press a button or make the user think that they need to refresh the page. This is why I'm using `setInterval`, I continuously make requests to the Google Ads JavaScript file that will be used to detect if AdBlock enabled.
I'm happy to pause my AdBlock for smaller sites that ask me to, or for newspaper sites that are supported by advertising, and I'm assuming that people visiting my site will also be OK with pausing AdBlock as a way of thanking me for the work that goes into what I share on my blog.
I'm mostly curious to see what happens to my site's traffic, and to see what impact it could have on the earnings I make from AdSense. Some of my questions are:
What will happen to the bounce rate if I request that AdBlock users pause AdBlock for my site?
What is the most effective amount of time to wait before requesting that a new user pause AdBlock for my site
What else can I include on my "Please Disable AdBlock" page to encourage new users to pause AdBlock on my site?
I'll have a good follow-up article to share with numbers from my AdSense and Google analytics.
One small issue
While ads are working on my site, I did notice that a console error related to AdSense:
K {message: "adsbygoogle.push() error: Only one 'enable_page_level_ads' allowed per page.", name: 'TagError', pbr: true, stack: "TagError: adsbygoogle.push() error: Only one 'enab…agead/js/adsbygoogle.js?client=ca-google:77:1130)"}message: "adsbygoogle.push() error: Only one 'enable_page_level_ads' allowed per page."name: "TagError"pbr: truestack: "TagError: adsbygoogle.push() error: Only one 'enable_page_level_ads' allowed per page. at go (http://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-google:219:326) at fo (http://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-google:218:788) at mo (http://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-google:225:365) at c (http://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-google:226:38) at no (http://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-google:226:156) at yo (http://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-google:235:248) at oo (http://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-google:232:89) at http://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-google:227:47 at Od.aa.ma (http://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-google:64:802) at Jf (http://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-google:77:1130)"
Here's a related issue on GitHub: https://github.com/nuxt-community/google-adsense-module/issues/141. I'm still not sure how to fix this issue. If anyone has any ideas, please let me know!
If you are interested in following my progress, feel free to subscribe to my MailChimp newsletter by filling out the form in the footer of my website, or by following me on any of the accounts listed on briancaffey.github.io/contact.