Yandex SmartCaptcha for Flutter
This package makes it easy to integrate Yandex SmartCaptcha into Flutter-based Android, iOS, and web apps. On Android and iOS, it uses a native WebView; on the web, it uses a DOM element and JavaScript interop. To learn more about the Yandex SmartCaptcha service, visit its official page.
Motivation
One day at work, I urgently needed to integrate Yandex SmartCaptcha into a mobile app, and the flutter_yandex_smartcaptcha package came to the rescue. However, I discovered a serious bug and reported it to the author. When they didn’t respond, I decided to create a similar package myself and learn how to publish packages on pub.dev in the process. End of story.
Usage
Super simple! Here’s the minimal example:
YandexSmartCaptcha(
config: CaptchaConfig(
clientKey: 'your-client-key',
),
onChallengeSolved: (token) {
// Handle the solved captcha token.
},
)
In most cases, you only need the YandexSmartCaptcha and CaptchaConfig classes. CaptchaController is optional and useful when you need to trigger validation, reset the widget, or destroy it programmatically.
- On mobile, the
YandexSmartCaptcha's parent widget should provide enough vertical space to accommodate both the "I'm not a robot" block and the challenge popup, as they are rendered inside a single WebView. - On the web, the parent widget only needs to provide enough vertical space for the "I'm not a robot" block (with a fixed height of around 100px), because Yandex fully controls the challenge popup.
Web support
You don't need to manually add the Yandex SmartCaptcha script to your
index.html, as theYandexSmartCaptchawidget loads it automatically when mounted into the widget tree.
On the web, YandexSmartCaptcha hosts the Yandex SmartCaptcha JavaScript widget. Use standard layout widgets such as Center, Padding, or SizedBox to control the position of the "I'm not a robot" block. Yandex controls the challenge popup's UI and behavior (just as it does on a regular website).
Some CaptchaConfig/YandexSmartCaptcha parameters (marked in the tables below) have no effect on the web.
The onChallengeShown/onChallengeHidden callbacks and CaptchaController methods remain fully available.
The web implementation is compatible with WebAssembly (Wasm).
CaptchaConfig parameters
This is an immutable configuration for Yandex SmartCaptcha and WebView content.
Ignored on web:
useWebViewMode,initialScale,allowUserScaling,maximumScale.
| Parameter | Required | Default | Description |
|---|---|---|---|
clientKey |
✔ | The client-side key passed to SmartCaptcha. | |
language |
ru |
The language used by the SmartCaptcha UI. | |
alwaysShowChallenge |
false |
Whether SmartCaptcha should always display a challenge (used for testing). | |
useInvisibleMode |
false |
Whether SmartCaptcha should run in invisible mode – without the "I'm not a robot" block. | |
badgePosition |
bottomRight |
The position of the Data Processing Notice (DPN) badge when useInvisibleMode is true. |
|
hideBadge |
false |
Whether to hide the DPN badge when useInvisibleMode is true. |
|
useWebViewMode* |
true |
Whether to enable a special mobile WebView optimization mode. | |
initialScale* |
1.0 |
The initial scale factor for the WebView content. | |
allowUserScaling* |
false |
Whether the user can scale the WebView content using gestures. | |
maximumScale* |
3.0 |
The maximum scale factor when allowUserScaling is true. |
YandexSmartCaptcha parameters
Control SmartCaptcha's runtime lifecycle, Flutter-level UI customization, and callback registration.
Ignored on web:
backgroundColor,loadingIndicator,onNavigationRequest,baseUrl.
| Parameter | Required | Default | Description |
|---|---|---|---|
config |
✔ | The configuration for this SmartCaptcha instance. | |
onChallengeSolved |
✔ | Called when the user successfully solves a challenge. | |
backgroundColor* |
null |
The background color of the SmartCaptcha widget container. | |
loadingIndicator* |
null |
A custom widget displayed while the SmartCaptcha script is loading. | |
onCaptchaReady |
null |
Called when the SmartCaptcha script is fully loaded and initialized. | |
onChallengeShown |
null |
Called when the challenge popup becomes visible. | |
onChallengeHidden |
null |
Called when the challenge popup is hidden or dismissed. | |
onTokenExpired |
null |
Called when the SmartCaptcha token expires after the challenge is successfully solved. | |
onNetworkError |
null |
Called when a network error occurs while loading or executing the SmartCaptcha script. | |
onJavaScriptError |
null |
Called when an uncaught JavaScript error occurs inside the SmartCaptcha script. | |
onNavigationRequest* |
null |
Called when a main-fraim navigation request is made inside the WebView. | |
controller |
null |
A controller for programmatically interacting with the SmartCaptcha instance. | |
baseUrl* |
null |
An HTTP(S) base URL used for domain validation and resolving origin policy issues. |
CaptchaController methods
Provide access to the SmartCaptcha JavaScript widget's imperative methods.
| Method | Description |
|---|---|
execute() |
Starts user validation by showing a challenge popup. Only works in invisible mode. |
reset() |
Resets the SmartCaptcha to its initial state. Only works after the challenge has been solved. |
destroy() |
Removes the SmartCaptcha widget and its associated event listeners. |
The controller exposes the same API on native and web platforms. Call these methods after onCaptchaReady fires.
Screenshots
- SmartCaptcha on a test screen (Android):
- SmartCaptcha in a real-world application (Android):
- SmartCaptcha on a test screen (Chrome):
Libraries
- yandex_smart_captcha
- Flutter integration for Yandex SmartCaptcha on Android, iOS, and Web.