hcaptcha

A hCaptcha verifier for Crystal apps.

hcaptcha

A hCaptcha verifier for Crystal apps.

Note The original repository is hosted at https://codeberg.org/fluck/hcaptcha.

Installation

  1. Add the dependency to your shard.yml:
dependencies:
  hcaptcha:
    codeberg: w0u7/hcaptcha
  1. Run shards install

Usage

Configuration

Require the shard in your app:

require "hcaptcha"

Add your configuration:

HCaptcha.configure do |settings|
  # Required
  settings.site_key = ENV.fetch("HCAPTCHA_SITE_KEY")
  settings.secret_key = ENV.fetch("HCAPTCHA_SECRET_KEY")

  # Optional
  settings.endpoint = "https://hcaptcha.com/siteverify" 
  settings.timeout = 5.seconds
  settings.retry_attempts = 3
  settings.retry_delays = [0.5, 1, 2]
  settings.script = "https://js.hcaptcha.com/1/api.js"
end

Front-end

Include the tags mixin:

abstract class BasePage
  include HCaptcha::Tags
end

Then add the hCaptcha script in the head of your page:

<%= hcaptcha_script %>

Or for Lucky Framework:

lucky_hcaptcha_script

This helper accepts the following options:

<%= hcaptcha_script(
  async: false,           # default is true
  defer: false,           # default is true
  language: "nl",         # default is nil
  render: "explicit",     # explicit|onload; default is nil (which means onload)
  onload: "yourCallback"  # default is nil
) %>

More info about these arguments can be found in the hCaptcha docs.

Note: All additional named arguments will be rendered as attributes on the HTML tag, with underscores converted to hyphens in the attribute names.

Next, add the hCaptcha container element:

<%= hcaptcha_container %>

Or for Lucky Framework:

lucky_hcaptcha_container

This helper accepts a class name:

<%= hcaptcha_container(class_name: "my-class-name") %>

All other named arguments will be rendered as attributes on the HTML tag, with underscores converted to hyphens in the attribute names:

<%= hcaptcha_container(data_theme: "dark", data_size: "compact") %>

Look at the hCaptcha docs for all the available configuration options, like data-theme, data-size, etc.

Back-end

Verify validity of the token:

hcaptcha_token = params["h-captcha-response"]
ip_address = request.remote_address

HCaptcha.verify?(hcaptcha_token, ip_address)
# => true

Or with more detail:

result = HCaptcha.verify(hcaptcha_token, ip_address)

if result.success?
  puts "Verification successful!"
  puts "Timestamp: #{result.challenge_timestamp}"
  puts "Hostname: #{result.hostname}"
else
  puts "Verification failed"
  
  result.error_codes.each do |code|
    puts "Error: #{code}"
  end
end

Handling exceptions:

begin
  result = HCaptcha.verify(hcaptcha_token)
  
  if result.success?
    # Handle successful verification
  else
    # Handle captcha failure (invalid response, expired, etc.)
  end
rescue HCaptcha::RequestError
  # Network connectivity issues, timeouts, connection failures
rescue HCaptcha::ResponseError
  # Invalid JSON response, unexpected HTTP status codes
end

Contributing

  1. Fork it (https://codeberg.org/fluck/hcaptcha/fork)
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'feat: add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

Contributors

  • Wout - creator and maintainer
Repository

hcaptcha

Owner
Statistic
  • 0
  • 0
  • 0
  • 0
  • 3
  • 3 months ago
  • October 9, 2025
License

Links
Synced at

Fri, 30 Jan 2026 12:58:36 GMT

Languages