From 11948a33cc4ff84752b7c907647a575168241a65 Mon Sep 17 00:00:00 2001 From: Zach Latta Date: Wed, 22 Oct 2025 19:18:06 +0000 Subject: [PATCH] Try to improve SEO --- .../api/hackatime/v1/hackatime_controller.rb | 8 +- app/controllers/docs_controller.rb | 4 +- app/controllers/static_pages_controller.rb | 24 +++-- app/helpers/application_helper.rb | 6 +- app/views/layouts/application.html.erb | 36 +++++++- app/views/shared/_nav.html.erb | 5 ++ .../static_pages/what_is_hackatime.html.erb | 87 +++++++++++++++++++ config/routes.rb | 1 + docs/getting-started/quick-start.md | 4 +- 9 files changed, 154 insertions(+), 21 deletions(-) create mode 100644 app/views/static_pages/what_is_hackatime.html.erb diff --git a/app/controllers/api/hackatime/v1/hackatime_controller.rb b/app/controllers/api/hackatime/v1/hackatime_controller.rb index 081df88..212f485 100644 --- a/app/controllers/api/hackatime/v1/hackatime_controller.rb +++ b/app/controllers/api/hackatime/v1/hackatime_controller.rb @@ -180,10 +180,10 @@ class Api::Hackatime::V1::HackatimeController < ApplicationController category_durations.map do |name, duration| name = name.presence || "unknown" name = case category - when "editor" then ApplicationController.helpers.display_editor_name(name) - when "operating_system" then ApplicationController.helpers.display_os_name(name) - when "language" then ApplicationController.helpers.display_language_name(name) - else name + when "editor" then ApplicationController.helpers.display_editor_name(name) + when "operating_system" then ApplicationController.helpers.display_os_name(name) + when "language" then ApplicationController.helpers.display_language_name(name) + else name end percent = ((duration / total_duration) * 100).round(2) hours = duration.to_i / 3600 diff --git a/app/controllers/docs_controller.rb b/app/controllers/docs_controller.rb index 307da65..40c0981 100644 --- a/app/controllers/docs_controller.rb +++ b/app/controllers/docs_controller.rb @@ -158,12 +158,12 @@ class DocsController < ApplicationController .strip description.length > 155 ? "#{description[0..155]}..." : description else - "#{title} - Complete documentation for Hackatime, the free and open source WakaTime alternative" + "#{title} - Complete documentation for Hackatime, the free and open source time tracker by Hack Club" end end def generate_doc_keywords(doc_path, title) - base_keywords = %w[hackatime wakatime alternative time tracking coding documentation] + base_keywords = %w[hackatime hack club open source tracker time tracking coding documentation] # Add path-specific keywords path_keywords = case doc_path diff --git a/app/controllers/static_pages_controller.rb b/app/controllers/static_pages_controller.rb index 2cd7618..1cc3a2c 100644 --- a/app/controllers/static_pages_controller.rb +++ b/app/controllers/static_pages_controller.rb @@ -84,6 +84,16 @@ class StaticPagesController < ApplicationController render :minimal_login, layout: "doorkeeper/application" end + def what_is_hackatime + @page_title = "What is Hackatime? - Free Coding Time Tracker" + @meta_description = "Hackatime is a free, open-source coding time tracker built by Hack Club for high school students. Track your programming time across 75+ editors and see your coding statistics." + @meta_keywords = "what is hackatime, hackatime definition, hack club time tracker, coding time tracker, programming statistics" + @og_title = @page_title + @og_description = @meta_description + @twitter_title = @page_title + @twitter_description = @meta_description + end + def mini_leaderboard use_timezone_leaderboard = current_user&.default_timezone_leaderboard @@ -235,7 +245,7 @@ class StaticPagesController < ApplicationController @page_title = title @meta_description = desc - @meta_keywords = "coding time tracker, programming stats, wakatime alternative, free time tracking, code statistics, high school programming, coding analytics" + @meta_keywords = "coding time tracker, programming stats, open source time tracker, hack club coding tracker, free time tracking, code statistics, high school programming, coding analytics" @og_title = title @og_description = desc @twitter_title = title @@ -263,7 +273,7 @@ class StaticPagesController < ApplicationController result[filter] = group_by_time.sort_by { |k, v| v } .reverse.map(&:first) .compact_blank - .map { |k| + .map { |k| if filter == :editor ApplicationController.helpers.display_editor_name(k) elsif filter == :operating_system @@ -338,11 +348,11 @@ class StaticPagesController < ApplicationController .first(10) .map { |k, v| label = case filter - when :editor then ApplicationController.helpers.display_editor_name(k) - when :operating_system then ApplicationController.helpers.display_os_name(k) - when :language then ApplicationController.helpers.display_language_name(k) - when :category then k - else k.capitalize + when :editor then ApplicationController.helpers.display_editor_name(k) + when :operating_system then ApplicationController.helpers.display_os_name(k) + when :language then ApplicationController.helpers.display_language_name(k) + when :category then k + else k.capitalize end [ label, v ] } diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index b68425e..8aa8a66 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -142,7 +142,7 @@ module ApplicationHelper def display_editor_name(editor) return "Unknown" if editor.blank? - + case editor.downcase when "vscode" then "VS Code" when "pycharm" then "PyCharm" @@ -161,7 +161,7 @@ module ApplicationHelper def display_os_name(os) return "Unknown" if os.blank? - + case os.downcase when "darwin" then "macOS" when "macos" then "macOS" @@ -171,7 +171,7 @@ module ApplicationHelper def display_language_name(language) return "Unknown" if language.blank? - + case language.downcase when "typescript" then "TypeScript" when "javascript" then "JavaScript" diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index d6c99be..bfaeb3c 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -8,7 +8,7 @@ - + @@ -20,7 +20,7 @@ - + @@ -34,7 +34,7 @@ - + <%= csrf_meta_tags %> @@ -54,11 +54,22 @@ "@context": "https://schema.org", "@type": "SoftwareApplication", "name": "Hackatime", + "alternateName": "Hack Club Hackatime", "applicationCategory": "DeveloperApplication", "operatingSystem": "Any", "description": "Track your coding time easily with Hackatime. A free tool to see how much time you spend programming in different languages and editors.", "url": "https://hackatime.hackclub.com", "downloadUrl": "https://hackatime.hackclub.com", + "sameAs": [ + "https://github.com/hackclub/hackatime", + "https://hackatime.hackclub.com/docs" + ], + "offers": { + "@type": "Offer", + "price": "0", + "priceCurrency": "USD", + "availability": "https://schema.org/InStock" + }, "author": { "@type": "Organization", "name": "Hack Club", @@ -95,6 +106,17 @@ } + + + <% if request.path == "/" %> +<% end %> + +
+
+

+ What is Hackatime? +

+ +
+

+ Hackatime is a free, open-source coding time tracker built by Hack Club for high school students and developers who want to understand their programming habits. +

+ +

+ Unlike other time tracking tools, Hackatime is completely free and designed specifically for the Hack Club community. It helps you see exactly how much time you spend coding, which programming languages you use most, and which editors you prefer. +

+ +

How Hackatime Works

+

+ Hackatime tracks your coding activity automatically by monitoring when you're actively typing in your code editor. It works with over 75 different editors including VS Code, JetBrains IDEs, vim, emacs, and many more. +

+ +

Why Hackatime Exists

+

+ Hackatime was created because Hack Club believes that the more time you spend making things, the better you get at building cool projects. By tracking your coding time, you can see your progress and stay motivated to keep building. +

+ +

Key Features of Hackatime

+
    +
  • Completely free - No paid plans or hidden costs
  • +
  • Open source - You can see the code and contribute
  • +
  • Works offline - Tracks your time even without internet
  • +
  • Real-time stats - See your coding activity as it happens
  • +
  • Community leaderboards - Compare with other Hack Clubbers
  • +
  • Privacy-focused - Minimal data is collected for time tracking. File contents are never sent to our servers or stored.
  • +
+ +

Getting Started with Hackatime

+

+ To start using Hackatime, simply sign in with your Hack Club Slack account or email. Once you're logged in, install the editor plugin for your preferred code editor and start coding. Hackatime will automatically begin tracking your time. +

+ +
+ <%= link_to "Get Started with Hackatime", root_path, class: "inline-block bg-primary text-white font-bold px-8 py-3 rounded-lg hover:bg-red-600 transition-colors duration-200" %> +
+
+ +
+

+ Hackatime is built and maintained by the Hack Club community. + <%= link_to "Learn more about Hack Club", "https://hackclub.com", target: "_blank", class: "text-primary hover:text-red underline" %>. +

+
+
+
diff --git a/config/routes.rb b/config/routes.rb index d8d95e7..e610ad3 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -69,6 +69,7 @@ Rails.application.routes.draw do end get "/minimal_login", to: "static_pages#minimal_login", as: :minimal_login + get "/what-is-hackatime", to: "static_pages#what_is_hackatime" # Auth routes get "/auth/slack", to: "sessions#new", as: :slack_auth diff --git a/docs/getting-started/quick-start.md b/docs/getting-started/quick-start.md index 01dceca..b266551 100644 --- a/docs/getting-started/quick-start.md +++ b/docs/getting-started/quick-start.md @@ -1,6 +1,6 @@ -# Hackatime Quick Start Guide - Free WakaTime Alternative +# Hackatime Quick Start Guide - Free Time Tracker -Get up and running with Hackatime in under 5 minutes! Start tracking your coding time across 40+ editors with our free, open source WakaTime alternative. +Get up and running with Hackatime in under 5 minutes! Start tracking your coding time across 40+ editors with our free, open source time tracker built by Hack Club. ## What is Hackatime?