<!-- View counter display -->
<div>
<span>Views: </span>
<spanid="view-count">Loading...</span>
</div>
<!-- Or use a badge -->
<imgsrc="https://your-domain.com/api/views/my-project/badge"alt="View Count" />
3. GitHub README Integration
# Add to your README.md

# With custom styling
[](https://your-domain.com)
๐ Complete API Reference
๐ POST /api/views/{project-name}
Purpose: Increment view count for a project
Parameter
Type
Description
Required
project-name
string
Unique project identifier (alphanumeric, hyphens, underscores, max 100 chars)
You can replicate this project for your own domain and data, completely isolated from this instance.
# 1) Fork and Clone the repositorygit clone https://github.com/Life-Experimentalist/ViewFlare.git
cd ViewFlare
# 2) Create your own Cloudflare Pages project + D1 DB# Configure your database bindings and ID in wrangler.toml# 3) Use your own custom domain (recommended)# Example: counter.yourdomain.com# 4) Keep your secrets unique# Set ADMIN_PASSWORD, DB binding, and project endpoints# 5) API calls auto-bind to current origin# The client dashboard uses window.location.origin automatically
Important: Do not hardcode counter.vkrishna04.me in your fork. Use your own domain and Cloudflare project settings to keep your data isolated.
โก Integration Examples
๐ JavaScript (Browser)
// Modern async/await approachasync functiontrackView(projectName) {
try {
const response = awaitfetch(`/api/views/${projectName}`, {
method: 'POST'
});
const data = await response.json();
if (data.success) {
console.log(`๐ Views: ${data.totalViews}`);
updateViewCounter(data.totalViews);
}
} catch (error) {
console.error('โ Failed to track view:', error);
}
}
// Get and display current statsasync functiondisplayViewCount(projectName) {
try {
const response = awaitfetch(`/api/views/${projectName}`);
const data = await response.json();
document.getElementById('view-count').textContent = data.totalViews.toLocaleString();
document.getElementById('unique-count').textContent = data.uniqueViews.toLocaleString();
} catch (error) {
console.error('โ Failed to load stats:', error);
}
}
// Auto-track when page loadsdocument.addEventListener('DOMContentLoaded', () => {
trackView('my-website');
displayViewCount('my-website');
});
# Using requests libraryimport requests
from typing import Dict, Optional
classViewCounter:
def__init__(self, base_url: str):
self.base_url = base_url.rstrip('/')
deftrack_view(self, project_name: str) -> Dict:
"""Track a view for the given project."""
url = f"{self.base_url}/api/views/{project_name}"try:
response = requests.post(url, timeout=5)
response.raise_for_status()
return response.json()
except requests.RequestException as e:
print(f"โ Failed to track view: {e}")
return {"success": False, "error": str(e)}
defget_stats(self, project_name: str) -> Dict:
"""Get current statistics for a project."""
url = f"{self.base_url}/api/views/{project_name}"try:
response = requests.get(url, timeout=5)
response.raise_for_status()
return response.json()
except requests.RequestException as e:
print(f"โ Failed to get stats: {e}")
return {"success": False, "error": str(e)}
# Usage
counter = ViewCounter("https://your-domain.com")
result = counter.track_view("my-python-project")
if result.get("success"):
print(f"๐ Total views: {result['totalViews']}")
๐ฆ Rust
// Add to Cargo.toml: reqwest = { version = "0.11", features = ["json"] }use reqwest;
use serde::{Deserialize, Serialize};
#[derive(Debug, Deserialize)]
structViewResponse {
success: bool,
#[serde(rename = "totalViews")]
total_views: u32,
#[serde(rename = "uniqueViews")]
unique_views: u32,
#[serde(rename = "projectName")]
project_name: String,
}
async fntrack_view(project_name: &str) -> Result<ViewResponse, reqwest::Error> {
let url = format!("https://your-domain.com/api/views/{}", project_name);
let client = reqwest::Client::new();
let response = client.post(&url).send().await?.json::<ViewResponse>().await?;
Ok(response)
}
๐ฏ Advanced Usage
โ๏ธ Environment Configuration
Configure your ViewFlare instance with these environment variables:
Variable
Default
Description
ADMIN_PASSWORD
admin123
Password for admin panel access
ENABLE_ADMIN
true
Enable/disable admin functionality
ENABLE_ANALYTICS
false
Enable detailed visitor tracking (uses more DB queries)
MAX_PROJECTS
100
Maximum number of projects to prevent abuse
๐๏ธ Self-Hosting
# Clone the repositorygit clone https://github.com/Life-Experimentalist/ViewFlare.git
cd ViewFlare
# Install dependenciesnpm install# Set up environment variablescp .env.example .env
# Create Cloudflare D1 databasenpm run db:createnpm run db:init# Deploy to Cloudflare Pagesnpm run deploy
ViewFlare is designed to stay within Cloudflare's free tier limits:
Database: Optimized queries (1-3 per request)
Functions: Minimal compute time
Caching: 1-hour badge cache reduces load
Analytics: Optional to save resources
๐ Security Features
# Security headers automatically included
Access-Control-Allow-Origin: *
Content-Security-Policy: default-src 'self'
X-Content-Type-Options: nosniff
# Rate limiting built-in
Max requests per IP: 60/minute (webhook)
Project name validation: Alphanumeric + hyphens/underscores (max 100 chars)
# Privacy-friendly visitor tracking
IP address hashing: SHA-256 with salt
GDPR compliant (no personal data stored)
Self-Hosting Setup
Deploy your own ViewFlare in minutes. Each fork gets its
own isolated D1 database โ completely separate from any
other instance.
1
Fork & Clone
Fork the repo on GitHub, then:
git clone
https://github.com/YOUR_USERNAME/cflair-counter.git
cd cflair-counter
2
Install Dependencies
npm install
3
Create D1 Database
wrangler d1 create cflaircounter-db
Copy the output database_id and paste
it into wrangler.toml.
4
Configure wrangler.toml
[[d1_databases]] binding = "DB" database_name =
"cflaircounter-db" database_id =
"YOUR_DATABASE_ID_HERE" [vars] ADMIN_PASSWORD =
"your-secure-password-here" # Your deployment will
be at: YOUR_ORIGIN
5
Initialize Schema
npm run db:init
6
Deploy
npm run deploy
After deploy, Cloudflare will show your Pages URL.
7
Custom Domain (Optional)
In your Cloudflare dashboard: Pages โ your project โ
Custom domains โ Add domain.
For external DNS, add a CNAME record pointing to
your Pages subdomain (e.g. yourproject.pages.dev).
๐งช Test Your Deployment
After deploying, verify your instance is working:
๐ Admin Panel
0
Total Views
0
Total Projects
โก Quick Actions
๐ Project Management
Loading projects...
โ Add New Project
Only alphanumeric characters, hyphens, and
underscores