Crovly

Flutter SDK

Add Crovly captcha to Flutter apps. WebView widget with Dart callbacks, works on Android and iOS.

Installation

Add to your pubspec.yaml:

dependencies:
  crovly_flutter: ^1.0.0

Then run:

flutter pub get

Get your site key at app.crovly.com.

Basic Usage

import 'package:crovly_flutter/crovly_flutter.dart';

class LoginPage extends StatefulWidget {
  @override
  State<LoginPage> createState() => _LoginPageState();
}

class _LoginPageState extends State<LoginPage> {
  String? _token;

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        TextField(decoration: InputDecoration(labelText: 'Email')),
        TextField(decoration: InputDecoration(labelText: 'Password'), obscureText: true),
        SizedBox(height: 16),
        CrovlyCaptcha(
          siteKey: 'YOUR_SITE_KEY',
          onVerify: (token) => setState(() => _token = token),
          onError: (code, message) => print('Error: $code - $message'),
        ),
        SizedBox(height: 16),
        ElevatedButton(
          onPressed: _token != null ? _handleSubmit : null,
          child: Text('Sign In'),
        ),
      ],
    );
  }

  Future<void> _handleSubmit() async {
    // Send _token to your backend for verification
  }
}

Parameters

ParameterTypeDefaultDescription
siteKeyStringYour public site key (required)
themeCrovlyTheme.autoWidget theme
sizeCrovlySize.normalWidget size mode
langString?Auto-detectLanguage code (e.g. 'tr', 'ar')
onVerifyvoid Function(String)Called on successful verification
onErrorvoid Function(String, String)Called on error
onExpireVoidCallbackCalled when token expires
apiUrlStringhttps://get.crovly.comWidget script CDN
widthdoubledouble.infinityWidget width
heightdouble65Widget height
decorationBoxDecoration?Container decoration

Theme Options

CrovlyCaptcha(
  siteKey: 'YOUR_SITE_KEY',
  theme: CrovlyTheme.dark,  // .light, .dark, or .auto
  onVerify: (token) => setState(() => _token = token),
)

Form Example

class ContactForm extends StatefulWidget {
  @override
  State<ContactForm> createState() => _ContactFormState();
}

class _ContactFormState extends State<ContactForm> {
  final _formKey = GlobalKey<FormState>();
  String? _token;

  @override
  Widget build(BuildContext context) {
    return Form(
      key: _formKey,
      child: Column(
        children: [
          TextFormField(
            decoration: InputDecoration(labelText: 'Name'),
            validator: (v) => v?.isEmpty == true ? 'Required' : null,
          ),
          TextFormField(
            decoration: InputDecoration(labelText: 'Message'),
            maxLines: 4,
            validator: (v) => v?.isEmpty == true ? 'Required' : null,
          ),
          SizedBox(height: 16),
          CrovlyCaptcha(
            siteKey: 'YOUR_SITE_KEY',
            theme: CrovlyTheme.auto,
            onVerify: (token) => setState(() => _token = token),
            onExpire: () => setState(() => _token = null),
          ),
          SizedBox(height: 16),
          ElevatedButton(
            onPressed: _token != null && _formKey.currentState!.validate()
                ? _submit
                : null,
            child: Text('Send'),
          ),
        ],
      ),
    );
  }

  Future<void> _submit() async {
    final response = await http.post(
      Uri.parse('https://your-api.com/contact'),
      headers: {'Content-Type': 'application/json'},
      body: jsonEncode({'token': _token}),
    );
    // Handle response
  }
}

Custom Styling

CrovlyCaptcha(
  siteKey: 'YOUR_SITE_KEY',
  width: 320,
  height: 80,
  decoration: BoxDecoration(
    borderRadius: BorderRadius.circular(12),
    border: Border.all(color: Colors.grey.shade300),
  ),
  onVerify: (token) => setState(() => _token = token),
)

Backend Verification

After getting the token, verify it on your server using any of the server-side SDKs:

// Using the Python SDK on your backend
from crovly import Crovly

client = Crovly("crvl_secret_YOUR_SECRET_KEY")
result = client.verify(token, expected_ip=request.remote_addr)

if not result.success:
    return {"error": "Captcha failed"}, 403

Platform Requirements

  • Android: minSdkVersion 19+
  • iOS: iOS 12.0+
  • Flutter: 3.10.0+
  • Dart: 3.0.0+

On this page