Introduction ¶
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.
The tutorial ¶
Step 1 Set up your Cloudflare Workers 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
Step 2 Create your Cloudflare Worker ¶
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
Step 3 Add the route for the Cloudflare Worker ¶
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:
Step 4 Implement the page view counting in the Worker ¶
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
});
}
Step 5 Create the floating modal for page views on your website ¶
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;
}
}
Step 6 Call the Cloudflare Worker from your website ¶
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">
Step 7 Complete! ¶
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!