Implementing hCaptcha in your Flutter App

You can get up and running in just a few minutes with Flutter and hCaptcha.

Below is a quick tutorial.

  1. Create a static HTML page on your server that contains your hCaptcha sitekey.
<script src="" async defer></script>
<body style='background-color: aqua;'>
<div style='height: 60px;'></div>
<form action="?" method="POST">
<div class="h-captcha"

function captchaCallback(response) {
if (typeof Captcha!=="undefined") {

2. Create a flutter Widget:

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';

class Captcha extends StatefulWidget {
Function callback;
State<StatefulWidget> createState() {
return CaptchaState();
class CaptchaState extends State<Captcha> {
WebViewController webViewController;
initState() {
Widget build(BuildContext context) {
return Center(
child: WebView(
initialUrl: "",
javascriptMode: JavascriptMode.unrestricted,
javascriptChannels: Set.from([
name: 'Captcha',
onMessageReceived: (JavascriptMessage message) {
// message contains the 'h-captcha-response' token.
// Send it to your server in the login or other
// data for verification via /siteverify
// see:
// print(message.message);
onWebViewCreated: (WebViewController w) {
webViewController = w;

3. And you’re pretty much done! To trigger the captcha, e.g. when a user presses “Sign up” in your app, just call it as follows:

builder: (context) {
return Captcha((String code)=>print("Code returned: "+code));

Use whatever callback you prefer, e.g. like this:

class GenericState extends State<Generic> {
void methodWithCaptcha(String captchaCode) {
// Do something with captchaCode, i.e. send to your
// server for validation by siteverify endpoint.

Widget build(BuildContext context) {
return Center(
child: FlatButton(
child: Text("Click here!"),
onPressed: () {
MaterialPageRoute(builder: (context) {
return Captcha(methodWithCaptcha);

To verify the passcode you just got from hCaptcha, you’ll just need to call siteverify on your server, as described here:

And that’s it!

Feel free to reach out to us with any questions.

inspiration: JVE999 on StackOverflow