How to add a page view counter to your static website using Cloudflare workers.
In this article we add dynamic functionality to a static website using Cloudflare Workers and linked KV database.
In this article we add dynamic functionality to a static website using Cloudflare Workers and linked KV database.
Today’s internet becomes more and more light, fast and, therefore, “static”. Programmers waive away heavy and cumbersome solutions and prefer to keep things as simple and fast, using and developing-wise, as possible. And in fact, there is no need to build every simple website using another heavy blog or content management system that, on top of that, often restrains developers and designers, usually makes the maintenance more expensive (not always though), etc.
Given all the above, more and more websites are being built using static website generators that allow programmers to build insanely fast, optimised, convenient and SEO-friendly websites with much less effort that it would take making it using some stout frameworks.
But there is, as almost always, a fly in the ointment.
Static sites usually don’t use any sort of databases “on the fly” and, thus, cannot “save” and “use” information generated (in a broad sense) by visitors. The simplest answer for that is to use some headless CMS that are in abundance nowadays. But there is little inconvenience, they either demand at least a VPS or, if hosted by the company that develops it, cost some money, and usually not that cheap. Especially if the only reason for having it is some simple thing such as, let’s say, a number of times some file has been downloaded, or counting post or page views on your website or maybe even very simple comments.
Today we will discover how we in Ambia.Studio solve this little problem easily and, that is not unimportant, usually for free for our clients.
Any information you decide your website needs should, first of all, be stored somewhere.
There are several possible ways to do so like:
If the functionality you plan to integrate is more or less complex it maybe you should use MongoDB solutions since it allows you to build applications almost indistinguishable from apps that use servers as backends. But in today's example we will build page views counter functionality, so we don’t need all the potential of MongoDB Realm and will use Cloudflare services called Workers and KVs for achieving the task. Mainly because it allows you to solve simple tasks like described earlier right in the browser, it hardly requires any configuration and works “out of the box”.
In short: Cloudflare Workers provide a serverless execution environment that allows you to create entirely new applications or augment existing ones without configuring or maintaining infrastructure. And they can be connected to Workers KV, that is a global, low-latency, key-value data store. What is good about workers is that it gives a pretty high free usage limit, exactly the first 100,000 requests each day are free, which is more than enough for small or even medium websites.
We won’t rewrite the same descriptions another time, for more information just visit the official website - https://workers.cloudflare.com/
And we, without wasting more time, will plunge right into the code and how to handle this very simple task.
First we need to create a Workers KV namespace that will be used by the worker. You can do it in your account, Workers -> KV. Click there “Create namespace” and enter the name, in my case the name is “POSTS_VIEWS”. After KV has been created let’s proceed to workers. Go to workers and click the “Create a Service” button, on the next page give it a name and choose a starter template (it does not matter which one will you choose).
Creating a Cloudflare worker
After you’ve created the worker, open it, go to “Settings” -> “Variables” and link tha KV namespace we created to the worker so that it has access to it.
Linking KV to the Worker
Now we can start writing the code. Since the task is pretty easy I will use Cloudflare’s quick editor. You can open it by clicking the “Quick edit” button on the worker’s page.
The default request handler, you probably already have it if you chose “Introduction (HTTP handler)” as a template for the worker.
addEventListener("fetch", (event) => {
event.respondWith(
handleRequest(event.request).catch(
(err) => new Response(err.stack, { status: 500 })
)
)
})
Then let’s create helper functions that work with our KV. To access it all you need is just type it’s name (this is why we linked KV earlier).
const setViews = (key, number) => POST_VIEWS.put(key, number)
const getViews = key => POST_VIEWS.get(key)
Now we have to handle the request itself
async function handleRequest(request, response) {
// getting params
const { searchParams } = new URL(request.url);
const key = searchParams.get('key')
if(!key)
return new Response("Invalid key", {status: 403})
let views = await getViews(key)
if (!views) {
await setViews(key, 1)
views = 1
} else {
setViews(key, +views + 1) // converting to number and adding 1
}
// CORS fix and return page view number
return new Response(JSON.stringify({ views }), {
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Methods": "GET",
"Access-Control-Allow-Origin": "https://yourwebsite.ca",
'Access-Control-Allow-Credentials': 'true',
},
})
}
That’s all! This tiny script will watch requests and if a request has a “key” in it’s query it will create (in case it’s the first request with such a key) or update the number of requests for a particular key.
This means that to get the amount of views for the page you need to send a simple GET request to https://[subdomain].workers.dev/?key=[someKey]
Now let’s write simple React and Vue code snippets that are ready to use with the worker.
For React we just need to use useEffect on page load and update a state variable with the result.
const [pageViews, setPageViews] = useState(0)
useEffect(() => {
fetch(`https://[subdomain].workers.dev/?key=${pageKey}`)
.then(res => res.json())
.then(({views}) => void setPageViews(views))
.catch(e => void console.error(e))
}, [])
And for Vue it would be:
<script setup>
const pageViews = ref(0)
onMounted(() => {
fetch(\`https://[subdomain].workers.dev/?key=${pageKey}\`)
.then(res => res.json()
.then(({views}) => void (pageViews.value = views))
.catch(e => void console.error(e))
})<script>
For a page key you can use it’s url path or some unique id.
That’s it! This way we added very simple database functionality to our completely static website, and it’s free (surely it won’t be if your website is popular enough to run out of free limits) without even leaving a browser. This is a very simple implementation of workers, of course you can use them in more interesting and complex ways. Maybe we will write about some other ideas later. Have a great day!
Get our free consultations if you need our help, or have some questions left.
Ambia.Studio © 2023