Nuxt Load Google Adsense Auto Ads

April 12, 2022

Important Notes

  • You can use Auto ads, but you must disable In-page ads. Why? In-page ads will cause JavaScript exception, as I believe ads injection by google intefere with the JavaScript hydration of Nuxt/Vue.js.
    • Ocassionally In-page ads will load fine, but it only loads on initial page request and will not load on further NuxtLink / vue-router navigation. Alternatively you could disable use of NuxtLink / RouterLink navigation and use <a> instead.
  • Vignette ads will still work, but it will intefere with NuxtLink /router navigation when Vignette ads popup, and trigger a new page request rather than a vue-router navigation.
  • Anchor ads will work fine.

Solution?

I create a component to load google ads manually.

  • I have to position the ads manually, as I can’t use In-page ads.
  • Auto ads is only enabled for the page if I use this component, else Auto ads won’t load (to prevent loading Adsense on page with no content).
  • Ads will load with NuxtLink / vue-router navigation, or dynamic loading of more content of an existing page.

Create components/GoogleAd.vue.

  • Create Display ads ad unit in Adsense, which is shown when type=display.
  • You can create other ad unit type as well. I create type=link which is In-feed ads.
<template>
  <component v-if="isShow" :class="_class" :is="tag">
    <ins v-if="type == 'link'"
      class="adsbygoogle"
      style="display:block"
      :data-ad-channel="channel"
      data-ad-format="fluid"
      data-ad-layout-key="-gb+7+v-no+1a7"
      data-ad-client="ca-pub-8122******"
      data-ad-slot="2872******"></ins>
    <ins v-else 
      class="adsbygoogle"
      style="display:block"
      :data-ad-channel="channel"
      data-ad-client="ca-pub-8122******"
      data-ad-slot="7368*****"
      data-ad-format="auto"
      data-full-width-responsive="true"></ins>
  </component>
</template>

<script>
export default {
  props: {
    '_class': Array, 
    'tag': {
      type: String,
      default: 'div'
    },
    'type': {
      type: String,
      default: 'display'
    },
    'channel': {
      type: String,
      default: 'nochannel'
    }
  },
  head() {
    if (this.isShow) {
      return {
        script: [
          { hid: 'adsense', src: 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-8122****', async: true, crossorigin: 'anonymous' }
        ]
      }
    }

    return { }
  },  
  data() {
    return {
      // use Nuxt RuntimeConfig to enable or disable Adsense
      isShow: this.$config.ENABLE_ADSENSE,
    }
  },
  mounted() {
    if (this.isShow) {
      this.$nextTick(() => {
        try {
          // this is required for each ad slot (calling this once will only load 1 ad)
          (window.adsbygoogle = window.adsbygoogle || []).push({})
        } catch (error) {
          console.error(error)
        }
      })
    }
  },
}
</script>

Usage

<template>
  <div>
    <google-ad :_class="['my-3']" :channel="main-page-top" :type="display" v-if="showTopAd" />

    <div>Content</div>

    <google-ad :_class="['my-3']" :channel="main-page-bottom" :type="display" v-if="showBottomAd" />
  </div>
</template>
This work is licensed under a
Creative Commons Attribution-NonCommercial 4.0 International License.