Crovly

React Native SDK

Add Crovly captcha to React Native and Expo apps. WebView-based widget with native callbacks for iOS and Android.

Installation

npm install @crovly/react-native react-native-webview

For Expo:

npx expo install @crovly/react-native react-native-webview

Get your site key at app.crovly.com.

Basic Usage

import { useState } from 'react';
import { CrovlyCaptcha } from '@crovly/react-native';

function LoginScreen() {
  const [token, setToken] = useState<string | null>(null);

  return (
    <View>
      <TextInput placeholder="Email" />
      <TextInput placeholder="Password" secureTextEntry />

      <CrovlyCaptcha
        siteKey="YOUR_SITE_KEY"
        onVerify={(token) => setToken(token)}
        onError={(code, msg) => console.error(code, msg)}
      />

      <Button
        title="Sign In"
        disabled={!token}
        onPress={() => handleLogin(token)}
      />
    </View>
  );
}

Props

PropTypeDefaultDescription
siteKeystringYour public site key (required)
theme'light' | 'dark' | 'auto''auto'Widget theme
size'normal' | 'compact''normal'Widget size mode
langstringAuto-detectLanguage code (e.g. 'tr', 'ar')
onVerify(token: string) => voidCalled on successful verification
onError(code: string, message: string) => voidCalled on error
onExpire() => voidCalled when token expires
apiUrlstringhttps://get.crovly.comWidget script CDN
containerStyleStyleProp<ViewStyle>Style for the container

Expo Example

import { useState } from 'react';
import { View, Button, Alert } from 'react-native';
import { CrovlyCaptcha } from '@crovly/react-native';

export default function App() {
  const [token, setToken] = useState<string | null>(null);

  const handleSubmit = async () => {
    const res = await fetch('https://your-api.com/submit', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ token }),
    });
    const data = await res.json();
    Alert.alert(data.success ? 'Success' : 'Failed');
  };

  return (
    <View style={{ flex: 1, justifyContent: 'center', padding: 20 }}>
      <CrovlyCaptcha
        siteKey="YOUR_SITE_KEY"
        theme="auto"
        onVerify={setToken}
        onExpire={() => setToken(null)}
      />
      <Button title="Submit" onPress={handleSubmit} disabled={!token} />
    </View>
  );
}

Dark Theme

<CrovlyCaptcha
  siteKey="YOUR_SITE_KEY"
  theme="dark"
  onVerify={setToken}
  containerStyle={{ borderRadius: 8, overflow: 'hidden' }}
/>

Backend Verification

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

import { Crovly } from '@crovly/node';

const crovly = new Crovly(process.env.CROVLY_SECRET_KEY!);
const result = await crovly.verify(token);

if (!result.success) {
  return res.status(403).json({ error: 'Captcha verification failed' });
}

TypeScript

Full type definitions included:

import type { CrovlyCaptchaProps, CrovlyErrorCode } from '@crovly/react-native';

On this page