Yes, we have implemented Google ReCAPTCHA on Sitecore Forms 10.3 Headless with Next.js. The steps involved are similar to creating a custom field in Sitecore Forms for MVC implementation, as outlined in the official Sitecore documentation here.
However, there is a crucial difference in the approach. In the MVC implementation, custom form elements have a "razor view" (.cshtml file) that defines how they are rendered. For the JSS (Headless) approach, this HTML part needs to be reimplemented, as Sitecore returns only configuration, not HTML structure. The .cshtml file cannot be directly reused for the JSS approach.
To associate your form element with JSX, you use a defaultFieldFactory
. Here's an example of how to create a custom field factory for Google ReCAPTCHA in React with the @sitecore-jss/sitecore-jss-react-forms
library:
// CustomFieldFactory.js
import React, { RefObject, useEffect, useRef, useState } from 'react';
import ReCAPTCHA from 'react-google-recaptcha';
import {
createDefaultFieldFactory,
FieldTypes,
ValueFieldProps,
} from '@sitecore-jss/sitecore-jss-react-forms';
export const AllFieldTypes = {
...FieldTypes,
GoogleRecaptcha: '{id here from path : /sitecore/system/Settings/Forms/Field Types/Security/Google Recaptcha}',
};
const CustomFieldFactory = createDefaultFieldFactory();
type ReCaptchaProps = ReCAPTCHA & {
captcha: {
parentElement: {
querySelector: (arg0: string) => Element | null;
};
};
};
CustomFieldFactory.setComponent(AllFieldTypes.GoogleRecaptcha, ({ field }: ValueFieldProps) => {
const [errorMessage, setErrorMessage] = useState<boolean>(false);
const recaptcha: RefObject<ReCaptchaProps> = useRef(null);
const handleRecaptchaChange = (value: string) => {
value?.length > 0 && setErrorMessage(false);
};
useEffect(() => {
let formButton;
if (recaptcha?.current != null) {
formButton = recaptcha?.current?.captcha?.parentElement?.querySelector('[type = "submit"]');
}
formButton &&
formButton?.addEventListener('click', (e) => {
const captchaValue = recaptcha?.current?.getValue();
if (captchaValue?.length === 0) {
setErrorMessage(true);
recaptcha?.current?.reset();
e.preventDefault();
}
});
}, [recaptcha]);
return (
<>
<ReCAPTCHA
sitekey={field?.model?.publicKey as string}
onChange={handleRecaptchaChange}
ref={recaptcha}
/>
{errorMessage && <span>{field?.model?.errorMessage as string}</span>}
</>
);
});
export default CustomFieldFactory;
Once you have created the custom field factory, pass it to your form rendering component, as shown in the following example:
// Forms.js
import { Form } from '@sitecore-jss/sitecore-jss-react-forms';
import React from 'react';
import { withRouter, NextRouter } from 'next/router';
import { sitecoreApiKey } from '../temp/config';
import CustomFieldFactory from './CustomFieldFactory';
const Forms = ({ fields, router }: { fields: never; router: NextRouter }) => {
return (
<div className="apply-now-container" id="apply-now-container">
<div className="container">
<Form
form={fields}
sitecoreApiHost={' '}
sitecoreApiKey={sitecoreApiKey}
onRedirect={(url) => router.push(url)}
fieldFactory={CustomFieldFactory}
/>
</div>
</div>
);
};
export default withRouter(Forms);
This custom field factory is designed to help the headless form package load the Google ReCAPTCHA schema.
You can refer to this blog for complete implementation - https://sitecorehelphouse.wordpress.com/2023/12/22/step-by-step-guide-to-integrating-google-recaptcha-in-sitecore-forms-for-headless-applications/
You can see this documentation from Sitecore JSS as well:
https://github.com/Sitecore/jss/blob/release/19.0.0/docs/data/routes/docs/techniques/forms/en.md