I’m trying to add a HubSpot form to my Next.js application and while the form displays correctly, I keep getting this runtime error: reCAPTCHA placeholder element must be an element or id. The form works but this error keeps showing up in the console.
Here’s my implementation:
useEffect(() => {
const formScript = document.createElement("script");
formScript.src = "https://js.hsforms.net/forms/v2.js";
document.body.appendChild(formScript);
formScript.addEventListener("load", () => {
if ((window as any).hbspt) {
(window as any).hbspt.forms.create({
portalId: "portal-123",
formId: "contact-form-456",
target: "#contactFormContainer",
});
}
});
}, []);
And the HTML element:
<div id="contactFormContainer"></div>
What could be causing this reCAPTCHA error and how can I fix it?
This happens when HubSpot’s reCAPTCHA can’t find its container element during setup. It’s a timing issue - the reCAPTCHA tries to load before your target div is actually ready in the DOM. I hit this same problem with a React project and fixed it by adding a short delay before creating the form. Wrap your hbspt.forms.create call in a setTimeout with 100-200ms delay so the DOM element loads first. Also check that your component isn’t server-side rendered - HubSpot’s script needs a browser environment. I’d throw some error handling around the form creation too, just in case it fails again.
Hit this same issue last month with HubSpot forms in Next.js. The problem is HubSpot’s reCAPTCHA tries to initialize before the DOM’s ready or when multiple scripts are loading at once. Fixed it by adding a cleanup function to prevent duplicate script loading and checking that the target element exists before creating the form. Wrap your hbspt.forms.create call with a target element check, then add cleanup in your useEffect to remove the script when the component unmounts. Also watch out for running this code multiple times - I kept seeing this error when components re-rendered and tried loading the script again while HubSpot was still processing the reCAPTCHA from the previous render.
The Problem:
You’re encountering the error reCAPTCHA placeholder element must be an element or id when integrating a HubSpot form into your Next.js application. The form itself functions correctly, but this error appears in the browser’s console. This typically indicates a timing conflict where the reCAPTCHA element is attempting to load before its designated container exists in the DOM.
TL;DR: The Quick Fix:
If you don’t require reCAPTCHA functionality for your HubSpot form, the simplest solution is to disable it. Modify your hbspt.forms.create call as follows:
(window as any).hbspt.forms.create({
portalId: "portal-123",
formId: "contact-form-456",
target: "#contactFormContainer",
recaptchaEnabled: false
});
Understanding the “Why” (The Root Cause):
The error arises because HubSpot’s reCAPTCHA needs a properly rendered HTML element (#contactFormContainer in your case) to attach itself to. If the HubSpot script loads before the target element is added to the DOM (Document Object Model), the reCAPTCHA initialization fails. This is common in JavaScript frameworks like React and Next.js where components render asynchronously. Disabling reCAPTCHA avoids this timing problem entirely.
Common Pitfalls & What to Check Next:
- Server-Side Rendering (SSR): Ensure your HubSpot form component isn’t rendered server-side. The HubSpot script relies on a browser environment to function correctly. Use client-side rendering.
- Duplicate Script Loading: If you’re seeing this error repeatedly, make sure the HubSpot script isn’t being loaded multiple times (due to component re-renders, for example). Implement a cleanup function in your
useEffect hook to remove the script when the component unmounts.
- Incorrect
target selector: Double-check that the target ID (#contactFormContainer in your example) precisely matches the ID of your div element in the HTML. A minor typo can cause this issue.
Still running into issues? Share your (sanitized) config files, the exact command you ran, and any other relevant details. The community is here to help!
This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.