Skip to content

How to get the real number of pageviews of a static site

New Course Coming Soon:

Get Really Good at Git

Given a static site, how do you get the real count of visitors?

Update: all major platforms have their own analytics solution now (Netlify, Vercel, Cloudflare..) also, you can self-host Plausible.

This is a static site. I use Google Analytics, and my audience is developers.

A perfect combination for inaccurate analytics data, since many developers use an ad blocker, which might (or might not, it depends) block the Google Analytics data from being transmitted to the servers. Some developers even completely block JavaScript, but I assume this is a smaller set of people, and so a less problematic thing.

I always had this doubt: what is the real number of visitors? What percentage of visitors am I looking at?

My hosting provider does not give any information about visits. I just know the bandwidth I consume.

So I decided to test an idea.

I include an image in every post, a very small image.

It’s nothing new: email marketing software automatically uses this “trick” to count open rates.

I used 1px x 1px SVG image, 141 bytes of data to have minimal impact.

I made a Node.js web server on Glitch. If you include the image in the website, like this:

<img src="https://<name-of-the-project>.glitch.me/pixel.svg" />

the Node.js web server living on that <name-of-the-project>.glitch.me URL is going to send the image back.

But first, it increments a value:

const express = require('express')
const app = express()
let counter = 0

app.use(
  express.static('public', {
    setHeaders: (res, path, stat) => {
      console.log(++counter)
    }
  })
)

const listener = app.listen(process.env.PORT, () => {
  console.log('Your app is listening on port ' + listener.address().port)
})

The important part of this app is the object we pass to express.static(). Normally we don’t pass an additional object to this method, but in there the setHeaders() function is provided so we can set some additional headers for the file which is going to be served.

We add our console.log() there, misusing this function for our purpose.

It’s very simple, and due to how Glitch works the counter will reset every time you update the app.

This is not supposed to be your analytics tool, of course. Just a way to quickly test if the analytics data matches the reality. Almost no one blocks images, normally.

And this can be done differently, since I use an SVG I could also just send a string back to the client, with the appropriate Content-Type header. I don’t know if that would be faster or not, I haven’t tried.

You could also serve a CSS file in the same way. I just happened to choose an image.

I let this run for 3-4 hours and the data, compared to the Google Analytics logs, showed me that about 10% of the people that visit my site don’t send data to Google Analytics.

Not a lot. I expected much more, like 2x the visitors. Or 50% more. But just a 10% increment.

Which is actually best for me, since this means the Google Analytics data is still very useful.

Are you intimidated by Git? Can’t figure out merge vs rebase? Are you afraid of screwing up something any time you have to do something in Git? Do you rely on ChatGPT or random people’s answer on StackOverflow to fix your problems? Your coworkers are tired of explaining Git to you all the time? Git is something we all need to use, but few of us really master it. I created this course to improve your Git (and GitHub) knowledge at a radical level. A course that helps you feel less frustrated with Git. Launching Summer 2024. Join the waiting list!

Here is how can I help you: