How to add adsense to Sveltekit?

Adding Google ads is a little tricky in Sveltekit. If not done right, the site can break if a user is using an adblock.

svelte logo

Want to build a Svelte/SvelteKit site? Hire Me.

Why use Ads?

Adsense is a great option to earn some money for your content.

I do not usually support ads but, it is a huge ecosystem and helps creators make a living off of their hard work put in to create content.

When ads are not intrusive they are fine. I prefer not to use popups on my site.

Popups distract your users. If you really want to use one then do it only with users’ consent. Something like a button that opens a popup.

Ads in a popup are the worst thing that can happen to a user. Never do this in your apps, websites.

Load ads in a place where the user expects them. Make a clear demarcation between the content and an ad.

Top-level script vs script inside HTML

A top-level script tag inside the Sveltekit component has special purposes.

But a script tag inside an HTML tag is treated as a normal script tag. However, if your script depends on the window object then you will have to handle it in some way.

This is why you can use the Google ads script inside a <div> or a <p> tag.

GoogleAds.svelte

<div>
  <script
    async
    src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-4146856286076977"
    crossorigin="anonymous"
  ></script>
  <!-- webjeda-top-banner-ad -->
  <ins
    class="adsbygoogle"
    style="display:block"
    data-ad-client="ca-pub-4146856286076977"
    data-ad-slot="1742538494"
    data-ad-format="horizontal"
    data-full-width-responsive="true"
  />
  <script>
    (adsbygoogle = window.adsbygoogle || []).push({});
  </script>
</div>

Issues with adblock

Adblock blocks the ad script(hence the component) from loading. This breaks the entire app.

The solution is to load the Google Ads svelte component dynamically after the app is mounted.

Dynamic import of Sveltekit components

Use the below snippet to load your svelte component load dynamically onMount. This is done because I wanted this not to be prerendered.

If it is prerendered and due to an adblock it isn’t able to load, then the entire app fails.

In +layout.svelte

<script>
  import { onMount } from "svelte";

  let Ads;
  onMount(async () => {
    Ads = (await import("$components/GoogleAds.svelte")).default;
  });
</script>

<svelte:component this="{Ads}" />

Detect if Adblock is enabled and stopping ads

Detecting Adblock in Svelte/Svetlekit is fairly easy. In vanilla JavaScript, we had to load a script named ad.js (or similar name) and check if the script loads. But in Svelte we can just use a store which will be set inside the Google Ads component.

/lib/stores.js

import { writable } from "svelte/store";

export const isAdLoaded = writable(false);

Now this store can be set inside a Google Ad component as shown below

GoogleAd.svelte

<script>
    import { isAdLoaded } from "$lib/stores";
    $isAdLoaded = true //sets the store to true implying Adblock is not enabled
</script>

<div>
  <script
    async
    src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-4146856286076977"
    crossorigin="anonymous"
  ></script>
  <!-- webjeda-top-banner-ad -->
  <ins
    class="adsbygoogle"
    style="display:block"
    data-ad-client="ca-pub-4146856286076977"
    data-ad-slot="1742538494"
    data-ad-format="horizontal"
    data-full-width-responsive="true"
  />
  <script>
    (adsbygoogle = window.adsbygoogle || []).push({});
  </script>
</div>

The store will be set to true if Ads load without problems. This store can be used elsewhere to load something else if Adblock is enabled.

<script>
  import GoogleAd from "$lib/GoogleAd.svelte"
  import { isAdLoaded } from "$lib/stores";
</script>

<GoogleAd />
{#if !$isAdLoaded}
  <p>Disable Adblock or some other component here</p>
{/if}

Find related articles

Let's discuss on Twitter