Yandex SmartCaptcha for Flutter

Pub Version Pub Points Codecov Dart Package Docs License: MIT Static Badge Static Badge

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 in-app 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 within 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 height of around 118px), because Yandex fully controls the challenge popup.

Web support

Note: The YandexSmartCaptcha widget automatically injects the Yandex SmartCaptcha script element when mounted, so you don't need to add it to your app's index.html.

On the web, YandexSmartCaptcha provides a host element for the Yandex SmartCaptcha HTML widget (aka "I'm not a robot" block). Use standard layout widgets such as Center, Padding, or SizedBox to control its position. Yandex fully controls the challenge popup's UI and behavior – just as it does on a regular website.

Note: The height of YandexSmartCaptcha is calculated by the SmartCaptcha script and cannot be set directly. The resulting height is usually appropriate, but you can adjust the displayed size using Transform.scale, if needed.

Certain CaptchaConfig/YandexSmartCaptcha parameters (marked with * in the tables below) are only applicable to native platforms and have no effect on web. However, almost all callbacks and CaptchaController methods remain 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's UI.
alwaysShowChallenge false Whether SmartCaptcha should always display a challenge (normally 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 with 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 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 validation 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 a JavaScript error occurs while loading or executing the SmartCaptcha script.
onNavigationRequest* null Called when a main-frame 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 properties and methods

Provide access to the SmartCaptcha's readiness state and imperative operations.

Member Description
isReady A ValueListenable<bool> that is true once SmartCaptcha is ready for interaction.
execute() Starts user validation by showing a challenge popup (only works in invisible mode).
reset() Resets the SmartCaptcha to its initial state (only works for a solved challenge).
destroy() Removes the SmartCaptcha HTML widget and its associated event listeners.
dispose() Releases the controller's resources.

The same members are available on all supported platforms.

Screenshots

  1. SmartCaptcha on a test screen (Android):
The initial state of the Yandex SmartCaptcha container with the 'I'm not a robot' block. The initial state of the Yandex SmartCaptcha pop-up, featuring a challenge for the user to solve. The state of the Yandex SmartCaptcha container with the 'I'm not a robot' box checked, after the user successfully solved the challenge.

  1. SmartCaptcha in a real-world application (Android):
The initial state of the Yandex SmartCaptcha container with the 'I'm not a robot' block, as seen in a real-world application. The initial state of the Yandex SmartCaptcha pop-up, featuring a challenge for the user to solve in a real-world application.

  1. SmartCaptcha on a test screen (Chrome):
The initial state of the Yandex SmartCaptcha pop-up, featuring a challenge for the user to solve. Chrome browser.

Libraries

yandex_smart_captcha
Flutter integration for Yandex SmartCaptcha on Android, iOS, and Web.