Ahoy & Blazer analytics integration
Adding user analytics and business intelligence to Rails apps with Ahoy and Blazer - implemented with Claude Code voice control
📹 Watch the Development Process
Watch the whole video at: youtube.com/watch?v=VT0iyi8y8Q4
Source code: github.com/stocklight/insidertrades.directory
Implementation Overview
This session involved implementing a complete analytics solution using two powerful Rails gems based on the excellent GoRails tutorial on Internal Metrics:
Original Claude Voice Prompt
"Add ahoy and blazer to this project. Create some find_or_initialise queries to track referral by domain, visit by landing page, and new users by day. Only allow the logged in user to see a button to an access blazer if the currently logged in user matches an ID specified in config somewhere"
Git Commit Details
View the complete implementation that Claude provided in this commit:
Blazer Analytics Queries
Here are the three core analytics queries that we generated:
# Blazer queries for analytics
blazer_queries = [
{
name: "Referrals by Domain",
description: "Track website visits grouped by referring domain",
statement: <<~SQL
SELECT
referring_domain,
COUNT(*) as visits,
COUNT(DISTINCT visitor_token) as unique_visitors,
DATE(started_at) as visit_date
FROM ahoy_visits
WHERE referring_domain IS NOT NULL
AND started_at >= date('now', '-30 days')
GROUP BY referring_domain, DATE(started_at)
ORDER BY visits DESC, visit_date DESC
LIMIT 50
SQL
},
{
name: "Visits by Landing Page",
description: "Track website visits grouped by landing page URL",
statement: <<~SQL
SELECT
landing_page,
COUNT(*) as visits,
COUNT(DISTINCT visitor_token) as unique_visitors,
DATE(started_at) as visit_date
FROM ahoy_visits
WHERE started_at >= date('now', '-30 days')
GROUP BY landing_page, DATE(started_at)
ORDER BY visits DESC, visit_date DESC
LIMIT 50
SQL
},
{
name: "New Users by Day",
description: "Track new user registrations grouped by day",
statement: <<~SQL
SELECT
DATE(created_at) as registration_date,
COUNT(*) as new_users,
COUNT(CASE WHEN google_user_id IS NOT NULL THEN 1 END) as google_signups,
COUNT(CASE WHEN google_user_id IS NULL THEN 1 END) as email_signups
FROM users
WHERE created_at >= date('now', '-30 days')
GROUP BY DATE(created_at)
ORDER BY registration_date DESC
SQL
}
]
blazer_queries.each do |query_attrs|
query = Blazer::Query.find_or_initialize_by(name: query_attrs[:name])
query.assign_attributes(query_attrs.merge(data_source: "main"))
if query.save
puts "✓ Created/Updated Blazer query: #{query.name}"
else
puts "✗ Error creating query #{query_attrs[:name]}: #{query.errors.full_messages.join(', ')}"
end
end
Key Features Delivered
📈 Analytics Tracking
Automatic visit tracking on all pages with referrer, landing page, and user agent data.
📊 Business Intelligence
Pre-built queries for traffic analysis, user behavior, and registration patterns.
🔒 Secure Access
Admin-only dashboard access with configurable user ID authorization.
⚙️ SQLite Integration
Properly configured for SQLite with environment-specific database paths.
Implementation Highlights
🔧 Configuration
- Gems: Added ahoy_matey and blazer to Gemfile
- Database: SQLite configuration with environment-specific paths
- Authentication: Admin user ID configuration in
config/initializers/admin_config.rb
- Routes: Mounted Blazer engine with proper authentication
🎯 Analytics Queries
Three business-critical queries implemented:
- Referrals by Domain - Track traffic sources and marketing effectiveness
- Visits by Landing Page - Monitor content performance and user behavior
- New Users by Day - Track growth patterns and signup methods
🔐 Security Features
- Admin-only access to Blazer dashboard via user ID whitelist
- Analytics navigation button visible only to authorized users
- Builds on existing Google Sign-In authentication system - users must be authenticated first
- Comprehensive test coverage for authentication scenarios