After months of running my portfolio and blog without any visitor insights, I finally decided it was time to implement analytics. But not just any analytics - I wanted a solution that respected user privacy, didn't require consent banners, and provided the data I actually needed.
The Analytics Dilemma
Most developers reach for Google Analytics by default, but I had several concerns:
- Privacy invasion: Extensive tracking and data collection
- GDPR compliance: Cookie banners and consent management
- Bloated scripts: ~28KB+ of JavaScript for basic analytics
- Over-engineering: Complex interface for simple needs
I needed something that would tell me:
- How many people visit my portfolio vs blog
- Which blog posts are most popular
- How many people try my Void Blocks game
- Where visitors come from (referrers)
Research Phase: Exploring Options
Option 1: Google Analytics 4
Pros: Comprehensive features, familiar interface, free forever Cons: Privacy concerns, requires GDPR compliance, heavy script, complex setup
Option 2: GitHub Pages Built-in Analytics
Status: Non-existent. GitHub Pages provides zero analytics capabilities beyond IP logging for security.
After extensive research, I discovered GitHub still doesn't provide native analytics for Pages sites, despite years of community requests. This remains one of the most requested features.
Option 3: Privacy-Focused Alternatives
I evaluated several privacy-first solutions:
Plausible Analytics: Excellent privacy focus, beautiful dashboard, but $9/month
Fathom Analytics: Similar to Plausible, but more expensive
Umami: Self-hosted option, requires server setup and maintenance
Option 4: GoatCounter - The Winner
Cost: Completely FREE (donation-supported) Privacy: No cookies, no personal data tracking, GDPR compliant Size: Only ~3.5KB script (75x lighter than Google Analytics) Features: All essential metrics without complexity API: REST endpoints for programmatic access
Implementation Strategy
Phase 1: Script Integration
I needed to add tracking to four distinct sections:
- Main Portfolio (
/index.html) - React app landing page - Blog Homepage (
/blog/templates/index.html) - Blog index with posts - Individual Posts (
/blog/templates/post.html) - Article pages - Void Blocks Game (
/public/games/void-blocks/index.html) - Game analytics
The implementation was straightforward - a single script tag before </body>:
<!-- GoatCounter Analytics --> <script data-goatcounter="https://jeffreyjose.goatcounter.com/count" async src="//gc.zgo.at/count.js"></script>Phase 2: Template Updates
For the blog system, I updated both templates:
Blog Index Template: Tracks blog homepage visits, tag filtering usage, and pagination navigation.
Post Template: Tracks individual article reads, reading time, and referral sources.
The React portfolio required adding the script to the root HTML template, ensuring tracking works across all single-page-app navigation.
Phase 3: Build and Deploy
After updating templates, I rebuilt the blog to propagate changes:
node blog/scripts/build.jsThis generated new HTML files with analytics scripts embedded. The build process updated all 12 blog posts, the index, archive page, and sitemap.
Architecture Decisions
Why Not Self-Hosted?
While Umami and Plausible offer self-hosted options, I chose GoatCounter's hosted service because:
- Zero maintenance: No server management or updates
- Reliability: Professional infrastructure and uptime
- Cost: Truly free vs hosting costs
- Focus: Spend time on content, not analytics infrastructure
Script Placement Strategy
I placed all scripts before </body> to ensure:
- Page content loads first (better UX)
- No blocking of critical rendering path
- Analytics don't interfere with existing animations
- Proper interaction with terminal effects and loading animations
What Gets Tracked
Portfolio Analytics
- Homepage visits and unique visitors
- Time on site and bounce rate
- Referrer sources (social, direct, search)
- Geographic distribution
Blog Analytics
- Individual post performance
- Most popular content categories
- Reading completion rates (via time on page)
- Tag-based content preferences
Game Analytics
- Void Blocks play sessions
- Game completion rates
- Player engagement metrics
Privacy Implementation
No Consent Required
GoatCounter's privacy-first approach means:
- No cookies stored
- No personal data collected
- No cross-site tracking
- No consent banners needed
Terminal Aesthetic Compliance
The solution maintains my 90s terminal aesthetic:
- No intrusive UI elements
- Lightweight script doesn't affect performance
- Clean, minimal dashboard matches design philosophy
Future Scope: View Count Display
Phase 2 Planning
The most exciting part is GoatCounter's API access. I'm planning to implement view counts directly on blog posts:
๐ analytics: 1,234 total views ยท 567 unique visitors ๐ this post: 89 views ๐ฎ void blocks: 156 playsAPI Integration Options
Build-time Fetching: Update view counts during blog rebuilds
// In blog/scripts/build.js const response = await fetch('https://jeffreyjose.goatcounter.com/api/v0/stats/hits', { headers: { 'Authorization': 'Bearer YOUR_API_KEY' } });Client-side Updates: Dynamic view counts with JavaScript
// Real-time view count updates fetch('/api/goatcounter-proxy/stats/hits/{path}') .then(r => r.json()) .then(data => updateViewCount(data.count));Rate Limits and Considerations
GoatCounter's API allows 4 requests per second, perfect for:
- Build-time batch updates
- Occasional real-time refreshes
- Popular posts widgets
- Analytics dashboard integration
Results and Performance
Immediate Benefits
- Zero impact on page load times
- No privacy concerns - visitors browse freely
- Clean data - only meaningful metrics
- Terminal aesthetic maintained throughout
Analytics Insights
Within hours of deployment, I could see:
- Blog posts attracting most traffic
- Popular content categories
- Visitor geographic distribution
- Referral source effectiveness
Lessons Learned
Research Pays Off
Spending time evaluating options prevented expensive mistakes. The "free" solutions (Google Analytics) had hidden costs in complexity and privacy concerns.
Privacy-First is User-First
Choosing GoatCounter improved user experience:
- No cookie prompts
- Faster page loads
- No tracking concerns
- Cleaner browsing experience
API Access is Crucial
Having programmatic access to analytics data opens possibilities:
- Custom dashboards
- View count displays
- Popular content widgets
- Integration with existing systems
Technical Implementation Details
File Changes Made
index.html- Portfolio trackingblog/templates/index.html- Blog homepageblog/templates/post.html- Individual postspublic/games/void-blocks/index.html- Game analyticsANALYTICS.md- Implementation documentation
Build Process Integration
The analytics scripts integrate seamlessly with the existing build system:
- Templates updated with tracking code
- Blog rebuild propagates changes
- Git deployment updates live site
- Analytics begin tracking immediately
Performance Impact
Measured impact on site performance:
- Script size: 3.5KB (vs 28KB+ for GA4)
- Load time: No measurable increase
- First paint: Unaffected
- JavaScript execution: Minimal
Future Enhancements
Phase 2: View Count Integration
- Generate GoatCounter API key
- Implement build-time view count fetching
- Design terminal-style view count display
- Add popular posts sidebar widget
Phase 3: Advanced Analytics
- Custom event tracking (game completions)
- Real-time dashboard integration
- Analytics API for portfolio projects
- Visitor engagement heatmaps
Phase 4: Content Optimization
- A/B testing for blog post titles
- Content performance analysis
- Referral source optimization
- User journey mapping
Conclusion
Implementing privacy-first analytics proved both technically straightforward and ethically satisfying. GoatCounter provides everything needed without compromise:
- User privacy respected completely
- Developer experience clean and simple
- Performance impact virtually zero
- Future flexibility through API access
The implementation took less than an hour but provides insights that will guide content strategy and technical decisions for years to come. Most importantly, visitors can browse freely without privacy concerns or intrusive tracking.
Sometimes the best technical solutions are the simplest ones that just work - exactly what GoatCounter delivers for privacy-conscious developers.