Skip to content

Nathan13888/VisitorBadgeReloaded

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Visitor Badge Reloaded ✨

10/25/25: Implemented rate limiting.

10/19/25: Migrated from Cloudflare KV to DO for storage backend

10/19/25: New website at https://vbr.nathanchung.dev

06/16/25: Migrated to Cloudflare Workers

11/20/24: Refactoring to ~~Rust πŸ¦€...~~Typescript

02/06/24: DEPRECATED vbr.wocr.tk (Freenom killed the domain... I renewed half a year ago btw). Please use the new domain name!

12/03/23: NOTICE - there sill be scheduled downtime between Dec 5th evening and Dec 7 morning due to server room maintainance ;)

7/19/23: Looking for new maintainers! If interested please submit a PR including "Maintainer" in the title.

6/20/23: VBR will be down for several days (shouldn't happen again). Sorry for the inconvenience :/

6/04/23: All cached records have been successfully restored!

6/03/23: VBR will be self-hosting Redis. Since CountAPI seem to be somewhat semi-permanantly broken, many existing badges have lost their count. However I was able to recover over 300k lines of logs, so I should be able to reconstruct a relatively accurate count of all the badges accesses within the past 3 months

5/28/23: It has come to my attention that countapi.xyz has gone down... It's quite unfortunate but it looks like I'll be implementing a new storage backend in the future. This will likely be part of a large rewrite of VBR. However, for the time being, data would be written to my own locally hosted Redis instance, then regularly backed up by myself. As for the lost data... we will have to live with the out-of-sync counts for the time being, I will work out a method to work out the count discrepancies in the future.

12/06/22: UPDATED HOSTING!!! Please use vbr.wocr.tk instead of the old Heroku domain (more details below)

Coverage Status

Visitor Badge Reloaded is a project inspired by visitor-badge which is no longer maintained, unfortunately.

In addition, it was missing some features which made it feel incomplete to me. It was also written using Python which I'm personally not a huge fan of, especially when used as a REST api.

Hence, something of better performance and functionality must be made!


🏎️ Benchmarks

A comprehensive benchmark suite is available to test the publicly hosted service! See benchmark/README.md for details.

Results:

alt text

Test Name Requests Success Rate Avg Response P95 P99 Throughput
Health Check 100 100.00% 73.21ms 137.28ms 1084.86ms 70.41 req/s
Badge - Sequential Requests 50 100.00% 53.13ms 76.75ms 253.03ms 15.75 req/s
Badge - With Hit Counting 100 100.00% 205.76ms 233.94ms 563.20ms 20.99 req/s
Badge - Read-Only (No Hits) 100 100.00% 59.65ms 98.79ms 208.14ms 59.84 req/s
Badge - Low Concurrency 100 100.00% 71.73ms 264.17ms 272.44ms 87.99 req/s
Badge - High Concurrency 200 100.00% 918.29ms 5121.83ms 11090.42ms 17.04 req/s
Badge - Customized Styling 100 100.00% 74.43ms 258.76ms 263.12ms 97.39 req/s
Analytics API 50 100.00% 79.96ms 140.41ms 272.62ms 69.08 req/s
Landing Page 50 100.00% 22.10ms 32.69ms 49.65ms 231.59 req/s
Stress Test - Burst Traffic 500 100.00% 1236.31ms 5134.62ms 19083.69ms 9.89 req/s

Performed on 2025-10-19 using a Macbook (M4 Pro) with a ~12.6ms average network latency to Cloudflare.

Quick Start:

# Run a quick performance check (~30 seconds)
bun run benchmark/quick-bench.ts

# Run the full benchmark suite (~5 minutes)
bun run bench

# Generate visual HTML report
bun run bench:report

What's tested:

  • Response time (avg, p50, p95, p99)
  • Throughput (requests per second)
  • Cache effectiveness
  • Concurrent request handling
  • Error rates and reliability
  • Real-world usage patterns

Results are saved to benchmark/results/ and can be compared over time to track performance trends.

βš™οΈ Settings

Badge Options

To use the options, append these flags to the URL of the badge!

Option Flag Description
Colour &color=<hex> Changes the colour of the embedded logo on the right-side of the badge.
Label Colour &lcolor=<hex> Changes the colour of the embedded logo on the left-side of the badge.
Style &style=<style> Sets the badge style based on Sheild.io's option.
Text &text=<format> Allows a custom string format to be set. Replaces CNT with the view count.
Label &label=<label> Replaces the label with a custom one.
Logo &logo=<logo name> Adds a logo to the badge (refer to examples). Find the logo name from Simple Icons
Logo Colour &lcolor=<hex> Changes the colour of the embedded logo on the left-side of the badge.
cache (deprecated) &cache=<anything here> Disabled by default. Changes the caching behaviour of the count by setting a time out. This works very poorly with Github's Camo CDN if enabled (since Camo doesn't respect the expiry headers unless it's expired). If the flag &cache= is followed by any text (anything more than one character), caching is enabled.
hit &hit=off Enabled by default. Determines if the badge will update the count (useful for duplicated badges or badges for just viewing the count). If left empty, it will update the count on each view. Any setting that is non-empty (isn't true or yes) is considered disabled.

Defaults:

  • Colour: "blue"
  • Style: "square"
  • Text: "Visitors"
  • Logo: no logo
  • Cache: disabled
  • Hit: enabled

Examples πŸ§ͺ

Different text background

Different label background

Different style

Different text

Different logo

🚒 Migrating From Visitor Badge

TLDR; REPLACE THE DOMAIN NAME
ie. 'visitor-badge.glitch.me/badge?page_id=YOURPAGEID' --> 'https://vbr.nathanchung.dev/badge?page_id=YOURPAGEID'

Visitor Badge Reloaded has ALL the same features as the original Visitor Badge with EVEN MORE FEATURES!

This means that all you have to do is replace the url of the badge with https://vbr.nathanchung.dev/badge?page_id=<your own page_id here>. The total visits will remain the exact same as well!

Also, VBR features could be configured as a HTTP query parameter!

Options (Old Option) (add as a HTTP query parameter) πŸ‘€

IMPORTANT: Other than the page_id option, there exists additional styling options and functional options (in the future). More details about the options could be found at the bottom of the Shields.io website. Also, all the options are specified as HTTP parameters!!!

  • page_id=<your id> --> identifies your badge, make this unique to yourself. eg. <your username.visitor.badge.reloaded or <username>-<username>
  • color=<colour here> --> the hex colour of the text background, do NOT include the #
  • lcolor=<colour here> --> the hex colour of the label background, do NOT include the #
  • style=<style name> --> refer to the Sheilds.IO website for the available options
  • text=<Some text other than "Visitors"> --> put a customizable label on your badge
  • logo --> logo to put beside the badge, go to https://simpleicons.org/ for the available names
  • logoColor --> refer to color for the formatting
  • cache --> *just put &cache=on at the end of the badge url

πŸš€ Feature Roadmap

  • Deployment
    • High availability (stateless)
    • Upgraded Shields.io
    • Automated scheduled backups: badge counts
  • API Improvements
    • Rate limiting, Prevent Abuse
    • /healthz endpoints
    • Uptime Monitoring
  • New Website
    • Personalized Analytics About Visitors

πŸ₯³ Supporting this project

I originally created this project because I personally wanted something that was built to my (relatively high) expectations of performance and customizability. I share this project and its hosted service to the public as I thought that this would be something that would benefit others. However, maintaining such a project and handling the demands of all the users that would use this service would incur additional work and costs for myself. Hence, it would be greatly appreciated if you could support this project by the following ways:

  1. Star ⭐ and share this project!
  2. Contribute to the development. Refer to Contributing
  3. Bug tracking! If you find any issues, please create an Issue so the problem could be fixed as soon as possible.

πŸ“¦ Deploying your own instance (self-hosting)

Please sauce PRs if there are problems ;)

Docker (V1)

This app could be packaged as a Docker image. Prebuilt docker images of VBR are also available on Docker Hub and on the Github Container Registry. Just run the relevant commands found in the Makefile. Then deploy to your choosen cloud service or even to your own server. However, note that there is no HTTPS support and VBR should be placed behind something else that provides HTTPS (eg. reverse proxy, Heroku...).

Cloudflare (V2)

# 1. install dependencies
bun i

# 2. use own workers kv
# update `wrangler.toml` with your own kv namespace id (avoid changing binding name to avoid regenerating types)
# @see https://developers.cloudflare.com/kv/get-started/

# 3. deploy to cloudflare
bun run deploy

πŸ’» Software Used

V2

  • Cloudflare Workers
  • Typescript
  • Hono
  • shields.io

V1

  • Golang
  • Docker
  • Mux (router)
  • Zerolog (logger)
  • Redis (Cache and Database)
  • shields.io

About

An extensible and modular visitor counter with a focus on performance and reliability. Serverless architecture.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors 4

  •  
  •  
  •  
  •