Gemini Page Counter

Page sections:

Creating A Page Counter for Gemini

Remember the page hit counters popular on 90s websites? I find gemini sites take me back to that era, so I was thinking it would be fun to recreate that on my gemini site. Using CGI it is pretty simple, and I will show you how.

I was thinking about how I wanted to do it. The easiest thing to do is just have a number stored somewhere and increment it by one when the page loads. Yes, that would be simple and effective, but what if I wanted to look at trends? I can record the timestamp of the page view into a running log. Gemini also has client certificates that can identify unique users, so I can also record certificate hashes to see unique page views. OK, this is getting too much like modern creepy Google Analytics. I think I just want to record the timestamp and that’s it!

You will need a gemini server that can run CGI. I am using gemserv and chose to use BASH as my CGI language for this task. Here is the script for my index.gmi page:

echo $'20 text/gemini\r\n'

# Section 1: Ignore my own page views
if [[ "${AUTH_TYPE}" == "Certificate" ]]; then
  if [[ "${REMOTE_USER}" == "Supernova-test" ]]; then

# Section 2: Write the timstamp to a log
if [[ writelog -eq 1 ]]; then
  datetime=`date +"%Y-%m-%d %T"`
  echo "${datetime}" >> /logs/counter.log

# Section 3: Print the index page static contents
cat ./index_gmi.txt

# Section 4: Print the page counter
count=`wc -l /logs/counter.log | awk '{ print $1 }'`
count=`printf "%07d" ${count}`
echo '```'
echo "Page Hit Count: ${count}"
echo '```'

In section 1 I decided to ignore my own page views to prevent inflating the count too much as I was testing. I did this by assigning a specific client certificate to my page, which I detect by the REMOTE_USER variable being of the value “Supernova-test”. If this is detected I set the “writelog” flag to 0 so that later a log entry won’t be written.

In section 2 I write a log entry if the “writelog” flag is 1 (everyone viewing the page except for me). I generate a date and time and add that to the log file. There will be one date time on each line looking like this:

2023-08-19 17:03:17
2023-08-19 22:12:54
2023-08-19 22:13:21
2023-08-19 22:17:13
2023-08-19 23:43:56

In section 3 I have a file index_gmi.txt which contains the actual contents of my index page in standard gemtext. A simple cat command of the file will print out the contents for the server to send back to the client.

In section 4 I count the number of lines in the log file, then I format the number to pad it with leading 0s so it is 7 digits long. Because that’s how we did it in the 90s 😁.

Well, that was pretty simple, wasn’t it?

With the date times in the log file I can now do simple stats, like view totals for each day, average by day of the week or hour of the day, etc. I haven’t done any of that yet but maybe that will be another post in the future.