Overview
Google reCAPTCHA supports multiple languages for the badge UI and challenge dialogs. The language prop allows you to specify which language reCAPTCHA should use, making your application accessible to users worldwide.
Quick Start
Set the language prop on GoogleReCaptchaProvider:
import { GoogleReCaptchaProvider } from 'react-google-recaptcha-v3' ;
function App () {
return (
< GoogleReCaptchaProvider
reCaptchaKey = "YOUR_SITE_KEY"
language = "es" // Spanish
>
< YourApp />
</ GoogleReCaptchaProvider >
);
}
How It Works
When you provide a language prop, the library:
Appends the hl (host language) parameter to the reCAPTCHA script URL
Loads the script as: https://www.google.com/recaptcha/api.js?render=KEY&hl=LANGUAGE
Google serves the appropriate language resources
Source reference: src/utils.ts:166-170
Supported Languages
Google reCAPTCHA supports 100+ languages and locales. Here are some common ones:
Western European Languages
Code Language enEnglish esSpanish frFrench deGerman itItalian ptPortuguese nlDutch noNorwegian svSwedish daDanish fiFinnish
Eastern European Languages
Code Language ruRussian plPolish ukUkrainian csCzech skSlovak huHungarian roRomanian bgBulgarian hrCroatian srSerbian
Code Language zh-CNChinese (Simplified) zh-TWChinese (Traditional) jaJapanese koKorean thThai viVietnamese idIndonesian msMalay filFilipino hiHindi
Code Language arArabic heHebrew faPersian trTurkish urUrdu
Code Language afAfrikaans amAmharic euBasque caCatalan etEstonian glGalician swSwahili zuZulu
Implementation Patterns
Static Language
Set a fixed language for your entire application:
function App () {
return (
< GoogleReCaptchaProvider
reCaptchaKey = "YOUR_SITE_KEY"
language = "fr" // Always French
>
< YourApp />
</ GoogleReCaptchaProvider >
);
}
Dynamic Language from State
Change the language based on user preferences:
import { useState } from 'react' ;
function App () {
const [ language , setLanguage ] = useState ( 'en' );
return (
< div >
< select value = { language } onChange = { ( e ) => setLanguage ( e . target . value ) } >
< option value = "en" > English </ option >
< option value = "es" > Español </ option >
< option value = "fr" > Français </ option >
< option value = "de" > Deutsch </ option >
< option value = "ja" > 日本語 </ option >
</ select >
< GoogleReCaptchaProvider
reCaptchaKey = "YOUR_SITE_KEY"
language = { language }
>
< YourApp />
</ GoogleReCaptchaProvider >
</ div >
);
}
Changing the language prop will cause the reCAPTCHA script to reload, which may briefly interrupt the user experience. Consider setting the language once on initial load.
Language from Browser Settings
Automatically detect the user’s browser language:
import { useMemo } from 'react' ;
function App () {
const browserLanguage = useMemo (() => {
// Get browser language (e.g., 'en-US', 'es-ES')
const fullLang = navigator . language || navigator . languages [ 0 ];
// Extract base language code (e.g., 'en' from 'en-US')
return fullLang . split ( '-' )[ 0 ];
}, []);
return (
< GoogleReCaptchaProvider
reCaptchaKey = "YOUR_SITE_KEY"
language = { browserLanguage }
>
< YourApp />
</ GoogleReCaptchaProvider >
);
}
Language from i18n Library
Integrate with popular i18n libraries:
react-i18next
react-intl
next-i18next (Next.js)
import { useTranslation } from 'react-i18next' ;
import { GoogleReCaptchaProvider } from 'react-google-recaptcha-v3' ;
function App () {
const { i18n } = useTranslation ();
return (
< GoogleReCaptchaProvider
reCaptchaKey = "YOUR_SITE_KEY"
language = { i18n . language }
>
< YourApp />
</ GoogleReCaptchaProvider >
);
}
Language with Fallback
Provide a fallback language if the user’s preferred language isn’t supported:
function App () {
const supportedLanguages = [ 'en' , 'es' , 'fr' , 'de' , 'ja' , 'zh-CN' ];
const language = useMemo (() => {
const browserLang = navigator . language . split ( '-' )[ 0 ];
// Use browser language if supported, otherwise default to English
return supportedLanguages . includes ( browserLang ) ? browserLang : 'en' ;
}, []);
return (
< GoogleReCaptchaProvider
reCaptchaKey = "YOUR_SITE_KEY"
language = { language }
>
< YourApp />
</ GoogleReCaptchaProvider >
);
}
Regional Variants
Some languages have regional variants (e.g., Portuguese in Brazil vs Portugal):
// Brazilian Portuguese
< GoogleReCaptchaProvider
reCaptchaKey = "YOUR_SITE_KEY"
language = "pt-BR"
>
< YourApp />
</ GoogleReCaptchaProvider >
// European Portuguese
< GoogleReCaptchaProvider
reCaptchaKey = "YOUR_SITE_KEY"
language = "pt-PT"
>
< YourApp />
</ GoogleReCaptchaProvider >
Common regional variants:
en-GB (British English) vs en (US English)
zh-CN (Simplified Chinese) vs zh-TW (Traditional Chinese)
es-419 (Latin American Spanish) vs es (European Spanish)
pt-BR (Brazilian Portuguese) vs pt-PT (European Portuguese)
fr-CA (Canadian French) vs fr (European French)
Right-to-Left (RTL) Languages
reCAPTCHA automatically handles RTL layout for languages like Arabic and Hebrew:
function App () {
return (
< GoogleReCaptchaProvider
reCaptchaKey = "YOUR_SITE_KEY"
language = "ar" // Arabic - automatically displays RTL
>
< div dir = "rtl" >
< YourApp />
</ div >
</ GoogleReCaptchaProvider >
);
}
RTL languages that are automatically handled:
ar - Arabic
he - Hebrew
fa - Persian
ur - Urdu
Complete Example: Multi-language Application
Here’s a full example with language selection, persistence, and i18n integration:
import { useState , useEffect , useCallback } from 'react' ;
import {
GoogleReCaptchaProvider ,
useGoogleReCaptcha
} from 'react-google-recaptcha-v3' ;
const SUPPORTED_LANGUAGES = [
{ code: 'en' , name: 'English' },
{ code: 'es' , name: 'Español' },
{ code: 'fr' , name: 'Français' },
{ code: 'de' , name: 'Deutsch' },
{ code: 'ja' , name: '日本語' },
{ code: 'zh-CN' , name: '简体中文' },
{ code: 'ar' , name: 'العربية' }
];
function LanguageSelector ({ currentLanguage , onLanguageChange }) {
return (
< select
value = { currentLanguage }
onChange = { ( e ) => onLanguageChange ( e . target . value ) }
style = { {
padding: '8px' ,
fontSize: '16px' ,
direction: currentLanguage === 'ar' ? 'rtl' : 'ltr'
} }
>
{ SUPPORTED_LANGUAGES . map ( lang => (
< option key = { lang . code } value = { lang . code } >
{ lang . name }
</ option >
)) }
</ select >
);
}
function ContactForm () {
const { executeRecaptcha } = useGoogleReCaptcha ();
const [ status , setStatus ] = useState ( '' );
const handleSubmit = useCallback ( async ( e ) => {
e . preventDefault ();
if ( ! executeRecaptcha ) {
setStatus ( 'reCAPTCHA not ready' );
return ;
}
const token = await executeRecaptcha ( 'contact_form' );
// Send to backend with language context
const response = await fetch ( '/api/contact' , {
method: 'POST' ,
headers: { 'Content-Type' : 'application/json' },
body: JSON . stringify ({
token ,
language: navigator . language
})
});
if ( response . ok ) {
setStatus ( '✓ Message sent!' );
}
}, [ executeRecaptcha ]);
return (
< form onSubmit = { handleSubmit } >
< input type = "email" placeholder = "Email" required />
< textarea placeholder = "Message" required />
< button type = "submit" > Send </ button >
{ status && < p > { status } </ p > }
</ form >
);
}
function App () {
// Initialize language from localStorage or browser
const [ language , setLanguage ] = useState (() => {
const saved = localStorage . getItem ( 'preferredLanguage' );
if ( saved ) return saved ;
const browserLang = navigator . language . split ( '-' )[ 0 ];
const supported = SUPPORTED_LANGUAGES . find ( l => l . code === browserLang );
return supported ? supported . code : 'en' ;
});
// Persist language preference
useEffect (() => {
localStorage . setItem ( 'preferredLanguage' , language );
// Set document direction for RTL languages
document . dir = [ 'ar' , 'he' , 'fa' , 'ur' ]. includes ( language ) ? 'rtl' : 'ltr' ;
}, [ language ]);
const handleLanguageChange = ( newLanguage ) => {
setLanguage ( newLanguage );
};
return (
< GoogleReCaptchaProvider
reCaptchaKey = { process . env . REACT_APP_RECAPTCHA_KEY }
language = { language }
>
< div className = "app" >
< header >
< h1 > Contact Us </ h1 >
< LanguageSelector
currentLanguage = { language }
onLanguageChange = { handleLanguageChange }
/>
</ header >
< main >
< ContactForm />
</ main >
</ div >
</ GoogleReCaptchaProvider >
);
}
export default App ;
Troubleshooting
Badge still shows in English
Common causes :
Language code is invalid or not supported
Script hasn’t reloaded after language change
Typo in language code
Solutions :
Verify language code against Google’s list
Check browser console for script loading errors
Use exact language codes (e.g., zh-CN not zh_CN)
Script reloads frequently
Cause : Language prop is changing on every render.Solution : Use useState, useMemo, or lift language state to avoid unnecessary changes:const language = useMemo (() => {
return navigator . language . split ( '-' )[ 0 ];
}, []); // Empty deps - calculate once
Regional variant not working
Cause : Not all languages have regional variants in reCAPTCHA.Solution : If a specific variant doesn’t work, fall back to the base language:const language = 'pt-BR' ; // Try regional first
// If issues occur, use just 'pt'
Cause : Page direction not set to RTL.Solution : Set dir attribute on root element:< div dir = { language === 'ar' ? 'rtl' : 'ltr' } >
< YourApp />
</ div >
Best Practices
Detect user language Use browser language detection to provide a better default experience, but allow users to override.
Persist preferences Save language selection to localStorage so users don’t have to select it again.
Match your app's language Keep reCAPTCHA language in sync with your application’s i18n system.
Provide fallbacks Default to a widely-spoken language (like English) if the user’s language isn’t supported.
Combining with Other Features
Language + Enterprise
< GoogleReCaptchaProvider
reCaptchaKey = "YOUR_ENTERPRISE_KEY"
language = "es"
useEnterprise = { true }
>
< YourApp />
</ GoogleReCaptchaProvider >
Language + Custom Container
< GoogleReCaptchaProvider
reCaptchaKey = "YOUR_SITE_KEY"
language = "ja"
container = { {
element: 'recaptcha-badge' ,
parameters: {
badge: 'inline' ,
theme: 'dark'
}
} }
>
< div id = "recaptcha-badge" />
</ GoogleReCaptchaProvider >
Language + recaptcha.net
< GoogleReCaptchaProvider
reCaptchaKey = "YOUR_SITE_KEY"
language = "zh-CN"
useRecaptchaNet = { true } // Important for China
>
< YourApp />
</ GoogleReCaptchaProvider >
Resources