Using Cloudflare Workers for page views modal on Hugo website


This is an experiment on the usage of Cloudflare Workers & Cloudflare Workers KV to display a page view count on all web pages on a website.

You can see what I am talking about bottom-left of this webpage! (and any other pages on my website)

This post will detail implementation from start to finish on my website which is built on Hugo and hosted on Cloudflare Pages.

You can read other Hugo-based posts from me here: Hugo website posts

Some of you may remember the 2000s fondly for websites that displayed the Visitors count on websites. I wanted to replicate that using technology from this era.

It’s easy and quick, using Cloudflare Workers with Cloudflare KV.

First, you need to create a KV namespace in your Cloudflare account. Follow the instructions in the official Cloudflare documentation: https://developers.cloudflare.com/workers/platform/kv

I created a namespace called websiteviews

In your Cloudflare account, create a new Worker. You can do this by following the instructions in the documentation: https://developers.cloudflare.com/workers/learning/getting-started

Add a route that maps your domain to your Cloudflare Worker. Make sure to replace yourdomain.com and your-worker with your actual domain and worker name.

yourdomain.com/stats/*

You can get to the Routes by going to the Triggers tab in the Worker you created in Step 2

Here is mine:

Edit your Worker’s code and implement the page view counting using the KV namespace you created in step 1:

addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request))
})

const PAGEVIEWS_KEY_PREFIX = 'pageviews:';

async function handleRequest(request) {
  const url = new URL(request.url);
  const key = PAGEVIEWS_KEY_PREFIX + url.pathname;

  const storedValue = await websiteviews.get(key, 'json');
  const currentCount = storedValue ? storedValue.count : 0;
  const newCount = currentCount + 1;

  await websiteviews.put(key, JSON.stringify({ count: newCount }));

  return new Response(JSON.stringify({ count: newCount }), {
    headers: { 'Content-Type': 'application/json' },
    status: 200
  });
}

Add the following HTML and CSS to your Hugo theme to create a responsive floating modal:

In my example, I add the below to the baseof.html that is in the directory layouts/_default

<div id="pageview-modal" class="pageview-modal">
  <div class="pageview-count">Page views: <span id="pageview-count-number">0</span></div>
</div>

In my example, I add the below CSS to a new file I created in the folder static called pageview.css

.pageview-modal {
  position: fixed;
  bottom: 10px;
  left: 10px;
  padding: 10px;
  background-color: rgba(0, 0, 0, 0.7);
  color: #fff;
  border-radius: 5px;
  font-size: 14px;
  z-index: 999;
}

@media (max-width: 600px) {
  .pageview-modal {
    font-size: 12px;
  }
}

Add the following JavaScript code to your Hugo site, which fetches the page view count from the Cloudflare Worker which in turn allows the Cloudflare Worker to +1 the count for each page view.

I added mine to a new file called 111.js that I placed in the static folder:

const statsUrl = '/stats';

async function fetchStats() {
  try {
    const response = await fetch(statsUrl + window.location.pathname);
    const data = await response.json();
    document.getElementById('stats-count-number').textContent = data.count;
  } catch (error) {
    console.error('Error fetching stats:', error);
  }
}

// Call the fetchStats function when the page is loaded
document.addEventListener('DOMContentLoaded', fetchStats);

Now with the created 111.js and pageview.css they need to be loaded into your webpages.

Add these files to baseof.html before the closing </body> tag

    <script src="/js/111.js"></script>
    <link rel="stylesheet" href="/css/pageview.css">

It should now work!

You should see the Page views: 0 modal bottom left of your website.

The same as what you can see bottom left of this website!

×
Page views: 0