Krizaka UI
Krizaka UI
Composants

Captcha

The bot check of a public form: Cloudflare Turnstile that shows nothing to a normal visitor, a framed box on the tokens only when a challenge needs them, and an accessible error with a retry.

Web · ✓Mobile · n/aBureau · ✓BêtaFormulaires
import { Captcha, CaptchaDisclosure } from "@krizaka/ui/captcha";

Web uniquement — React, depuis @krizaka/ui/captcha. Bêta : son API peut encore changer à une version mineure.

  • Mobile · n/a. Turnstile is a web widget; a phone app proves itself with its own session.

Pourquoi il est là. krizaka.com's contact form and the blog's newsletter form (the public forms, behind Cloudflare Turnstile).

Quand l’utiliser

  • A public form anyone can post (contact, newsletter, sign-up) that the server verifies with Turnstile's siteverify.
  • When the check must not weigh on the page: it runs in the background and appears only if Cloudflare asks.

Quand ne pas l’utiliser

  • A signed-in action: the session already proves who acts.
  • A confirmation of a destructive action.À la place : Confirm button

Installation

Installer

npm install @krizaka/ui @krizaka/tailwind @krizaka/tokens tailwindcss

Styles

@import "tailwindcss";
@import "@krizaka/tailwind";
@import "@krizaka/ui/tailwind.css";

Importer

import { Captcha, CaptchaDisclosure } from "@krizaka/ui/captcha";

Exemples

A form with its check

The submit waits for the token; the disclosure sits under it.

The disclosure line

« Protected by Cloudflare Turnstile · Privacy · Terms », in English or French.

Props

Captcha

The bot check of a public form, Cloudflare Turnstile that stays out of the way: managed mode with appearance: "interaction-only", so a normal visitor sees nothing — the check runs in the background and onToken fires. Only when Cloudflare needs the visitor does a framed box appear, on the tokens (radius, border, theme). If the check cannot run, an alert with a retry button replaces it. Pair it with CaptchaDisclosure under the submit.

PropTypeDéfautDescription
onTokenrequis(token: string | null) => void—The token once the check passes; null when it expires, fails or the theme redraws the widget.
siteKeyrequisstring—The widget's public site key. Empty → nothing is rendered and no token is asked (local dev, tests).
classNamestring—Classes added to the root.
labelsPartial<CaptchaLabels>—Words to say otherwise; the rest comes from the locale.
localestringenThe language of the widget and of the words: "en", "fr"…
theme"auto" | "light" | "dark"autoauto follows the page (html.light / data-theme, redrawn when it flips).

CaptchaDisclosure

« Protected by Cloudflare Turnstile · Privacy · Terms »: the line Cloudflare's terms ask for under the submit button.

PropTypeDéfautDescription
classNamestring—Classes added to the root.
labelsPartial<CaptchaLabels>—Words to say otherwise; the rest comes from the locale.
localestringenThe language of the line: "en", "fr"…
privacyHrefstringhttps://www.cloudflare.com/privacypolicy/The privacy link; Cloudflare's privacy policy by default.
termsHrefstringhttps://www.cloudflare.com/website-terms/The terms link; Cloudflare's website terms by default.

Accessibilité

  • The widget sits in a group named by labels.group; a failure is announced as an alert, with a button to try again.
  • The disclosure links open in a new tab with rel="noopener noreferrer".

Clavier

TouchesAction
TabReaches the Cloudflare challenge when it shows, and the Try again button on error.

Bonnes pratiques

  • Verify the token on the server and fail closed: a missing or refused token is a 400, whatever the browser says.
  • Put CaptchaDisclosure under the submit button: Cloudflare's terms ask for the privacy and terms links when the widget is hidden.
  • Disable the submit while onToken has not given a token, and remount the component (key) after a refused token.
  • Pass the site's locale; the theme follows the page (html.light or data-theme) and redraws when it flips.

Générée depuis le code de @krizaka/ui 3.63.1 : son meta.ts, ses exemples et ses types.Modifier cette documentation sur GitHub

Sur cette page