First of all, yes ads suck. I recently started using Google AdSense on my blog to recoup the costs of I switched to Ghost from GitHub Pages which is completely free and a great way to host a static blog. I wanted some more flexibility however and also wanted a newsletter subscription service so I found I’m currently on their Starter Plan which does not allow you to upload an ads.txt file from Google AdSense.

If you don’t have the ads.txt file Google AdSense displays a warning in your AdSense portal that your earnings are at risk, Authorised Digital Sellers, or ads.txt is an IAB Tech Lab initiative that helps ensure that your digital ad inventory is only sold through sellers (such as AdSense) who you’ve identified as authorised. Creating your own ads.txt file gives you more control over who’s allowed to sell ads on your site and helps prevent counterfeit inventory from being presented to advertisers.


Since I can’t fix it in Ghost directly (you can on the more expensive plans, just not the starter plan) I needed to look for a workaround, the fine folks over at Ghost pointed me to Cloudflare which I was already using as a registrar, DNS, and for DDOS protection. They also provide the abilitly to deploy serverless code using their Cloudflare Workers service, this allows me to deploy JavaScript to Cloudflare’s edge, which ultimatly provides a way to host and manage my own ads.txt file, yay!

How it works

First of you need a to use Cloudflare for DNS services for your domain, it is free and works wonderfully.

In the Cloudflare portal click on ‘Workers’


Setup your free Cloudflare Workers subdomain by selecting your domain and clicking ‘Set up’


There is a free plan, with some limitations of course, or you can opt to go for the Pay-as-you-go model. Select the one you want and click (in my case) ‘Continue with Free’.


Now download your ads.txt file from your Google AdSense portal and open it. Copy and paste your values in the script below.

async function handleRequest(request) {
  const init = {
    headers: {
      'content-type': 'text/plain',
  return new Response(adstxt, init)
addEventListener('fetch', event => {
  return event.respondWith(handleRequest(event.request))
const adstxt =  `#, pub-xxxxxxxxxxx, DIRECT, fxxxxxxxxx 

next click ‘Save and Deploy’


Now back to your domain and select ‘Workers’ and click ‘Add route’


Set the Route to and select the Worker you just created, then click ‘Save’


Verify everything is set as expected.


Now go to your website and verify if the file is being served. Done! As if I needed another reason to love Cloudflare 🤗

The Google AdSense portal will take a few days to update the ads.txt notification.