hcaptcha
hcaptcha
A hCaptcha verifier for Crystal apps.
Note The original repository is hosted at https://codeberg.org/fluck/hcaptcha.
Installation
- Add the dependency to your
shard.yml:
dependencies:
hcaptcha:
codeberg: w0u7/hcaptcha
- 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
- Fork it (https://codeberg.org/fluck/hcaptcha/fork)
- Create your feature branch (
git checkout -b my-new-feature) - Commit your changes (
git commit -am 'feat: add some feature') - Push to the branch (
git push origin my-new-feature) - Create a new Pull Request
Contributors
- Wout - creator and maintainer
hcaptcha
- 0
- 0
- 0
- 0
- 3
- 3 months ago
- October 9, 2025
Fri, 30 Jan 2026 12:58:36 GMT