A page view counter for people who dislike being counted.
Counts views. Not people. Not cookies. Not fingerprints.
“What cannot be mended must be transcended.” — Ursula K. Le Guin
Viewlet is a small, self-hostable badge that tells you how many times a page has been viewed. It does not track visitors, build profiles, or phone home to analytics companies. It just counts.
Add one line to your README.md:
Replace yourname.yourrepo with a unique identifier. Done.
All parameters are optional except page_id.
| Parameter | Required | Description | Default |
|---|---|---|---|
page_id |
✅ | Unique identifier for your page | — |
left_text |
— | Left-side label | visitors |
left_color |
— | Left side color (name or hex) | #595959 |
right_color |
— | Right side color (name or hex) | #1283c3 |
format |
— | Compact number display (1K / 1M) | disabled |
logo |
— | Built-in local logo slug from the Simple Icons catalog | — |
radius |
— | Badge corner radius (px) | 3 |
height |
— | Badge height (px), scales proportionally | 20 |
query_only |
— | Query without incrementing counter | disabled |
period |
— | total (all-time) or daily page views |
total |
date |
— | With period=daily, show views for a specific YYYY-MM-DD |
today |
style |
— | Badge style for logo variant: flat or social |
flat |
logoSize |
— | Set auto to fit non-square logos to their bounding box |
24x24 |
Note: For hex colors with
#, URL-encode#as%23.
Example:#595959→%23595959
Default style
Custom colors
Custom label
Compact format (1K / 1M)
Built-in logo
Use any icon from the Simple Icons catalog. The value can be the official slug, the icon title, or the legacy hyphenated title.
Custom logo color
Light/dark logo variant
Use style=social to switch to a dark logo variant when the default icon color is too bright.
Auto-size logo
Set logoSize=auto to fit non-square icons to their actual bounding box.
Example values: github, gitlab, vercel, docker, npm, discord, x, githubactions, netlify, cloudflare, telegram, wechat, youtube, react, vite, vuedotjs
Browse the full Simple Icons catalog in the online builder.
Query only (don't increment)
Combo: all together
Daily views
Historical daily views
Versioned endpoints
Visit /dashboard (or /dashboard@latest) and enter your page_id to see:
- Daily page view trends
- Hourly breakdown for today
- Top referrers
It runs entirely in the browser and uses Chart.js to visualize data from the public API. No account or API key needed.
Example: https://viewlet.livrasand.com/dashboard@latest
The dashboard can import the current total view count from https://visitor-badge.laobi.icu into a matching page_id in Viewlet. The imported value is added to the existing counter (merge, not overwrite).
- Only the current total can be imported; daily/hourly/referrer history is not exposed by the source service.
- Source and destination
page_idmust be identical.
Public, read-only endpoints. All accept an optional version prefix (@1.0.0, @latest).
GET /api@latest/stats?page_id=livrasand.viewlet&range=30|all&granularity=day|hour- Returns
[{label, count}, ...]
- Returns
GET /api@latest/referrers?page_id=livrasand.viewlet&range=30|all&limit=50- Returns
[{referer, count}, ...]
- Returns
Example:
curl "https://viewlet.livrasand.com/api@latest/stats?page_id=livrasand.viewlet&range=7&granularity=day"[
{"label": "2026-08-07", "count": 12},
{"label": "2026-08-08", "count": 24},
{"label": "2026-08-09", "count": 0}
]curl "https://viewlet.livrasand.com/api@latest/referrers?page_id=livrasand.viewlet&range=7&limit=10"[
{"referer": "github.com", "count": 42},
{"referer": "direct", "count": 11}
]Use range=all to retrieve the full stored history. No authentication required — badge data is already public.
<img src="https://viewlet.livrasand.com/badge?page_id=yourname.yourrepo" alt="viewlet">Clone the repo, install dependencies, and run:
git clone https://github.com/livrasand/viewlet.git
cd viewlet
pip install -r requirements.txt
# Set your count API endpoint in main.py
python3 main.pyRequires a compatible counting backend, or uses the built-in SQLite fallback. See main.py for details.
- ✅ No registration
- ✅ Custom colors (left & right)
- ✅ Custom label text
- ✅ Compact number format (1K / 1M)
- ✅ Total and daily view badges
- ✅ Historical daily badges (
date=YYYY-MM-DD) - ✅ Public analytics dashboard
- ✅ Query-only mode (no count increment)
- ✅ Lightweight SVG response
Viewlet counts page views, not people.
We do not store cookies, fingerprints, personal profiles, advertising IDs, or unique visitor identifiers. Viewlet only records anonymous page view events with a timestamp and optional referrer.
- NO cookies
- NO fingerprinting
- NO personal profiles
- NO advertising IDs
- NO cross-site tracking
- NO unique visitor tracking
- NO telemetry
- NO subscriptions
- NO forced upgrades
- NO automatic updates
Your infrastructure, your choice. Pin a specific release:
viewlet:1.0.0
/badge@1.0.0
/api@1.0.0
/dashboard@1.0.0
Or explicitly opt into latest:
viewlet:latest
/badge@latest
The original visitor-badge is a convenient hosted service, but I wanted something I could run myself. I wanted to know where the data goes. I wanted to pin a version, host it on my own server, and turn off anything I did not ask for.
This fork keeps the simple badge idea and removes the surveillance-adjacent parts.
“I come with empty hands and the desire to unbuild walls.” — Ursula K. Le Guin, The Dispossessed
A page view counter should be a hammer, not a surveillance drone. It should count one thing, store the minimum, and get out of the way.
This project was written by a human. I do not use LLMs to write code, issues, or documentation. I do not want AI-generated slop in this repository. If you submit a patch, make sure it is yours.
This project is mainly therapeutic. I had to get it out of my system.
Forked from jwenjian/visitor-badge with optimizations and updated infrastructure.
Share freely. Keep your privacy.
✨ Thanks for visiting Viewlet!