Google Recaptcha & Gatsby Error: reCAPTCHA placeholder element must be an element or id

Solution for Google Recaptcha & Gatsby Error: reCAPTCHA placeholder element must be an element or id
is Given Below:

I’m trying to add recaptcha v2 to my Gatsby/Netlify site form and i’m missing the last part that is actually displaying the widget. It just doesn’t show up where it is placed.

So far my code is this

The gatsby-ssr.js file:

import React from "react"

export const onRenderBody = ({ setHeadComponents, setPostBodyComponents }) => {
  setHeadComponents([
    <script
      dangerouslySetInnerHTML={{
        __html: `
        function onloadCallback() {
          grecaptcha.render(document.getElementById('g-recaptcha'), {
          "sitekey": '6LfMWLkaAAAAAFYM11ctU1Dxfz_v3SVrAKLOR3rM',
        })
      }
     `,
      }}
    />,
  ])

  setPostBodyComponents([
    <script
      key="abc"
      type="text/javascript"
      src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit"
      async
      defer1
    />,
  ])
}

And the contact form:

<Form className="contact-form" method="post" data-netlify-recaptcha="true" data-netlify="true" netlify-honeypot="bot-field">
  ...
  <p className="hidden">
    <label>Don’t fill this out if you’re human: <input name="bot-field" /></label>
  </p>
  ...
  <Form.Group id="recaptcha-container">
    <div id="g-recaptcha" className="g-recaptcha" data-netlify-recaptcha="true" render="explicit"></div>
  </Form.Group>
  ...
</Form>

The error “Uncaught (in promise) Error: reCAPTCHA placeholder element must be an element or id” appeared before I added any Netlify attributes to my form, so I’m pretty sure that has nothing to do with it.

Any ideas? Thanks.

I think your issue is that you are embedding the script directly outside the scope of React so it’s never rehydrated when it’s loaded. The easiest way is by adding react-google-recaptcha component:

<Form className="contact-form" method="post" data-netlify-recaptcha="true" action="/" data-netlify="true" netlify-honeypot="bot-field">
  ...
  <p className="hidden">
    <label>Don’t fill this out if you’re human: <input name="bot-field" /></label>
  </p>
  ...
  <Form.Group id="recaptcha-container">
  <ReCAPTCHA
    sitekey="Your client site key"
    onChange={onChange}
  />,
  </Form.Group>
  ...
</Form>

As I said, I don’t think you need the gatsby-ssr.js implementation, you can achieve a more native implementation by adding React components, as the snippet above shows. You’ll need to get the value and send it to Netlify request. I would recommend you to set an action in the form component too.

You are also missing a key property of the form: the name. Without that, Netlify will never know how is your form named and won’t show it in the dashboard (you will need to send it too).

Keep in mind that reCAPTCHA will never be loaded locally unless you configure your backoffice to accept local requests (127.0.0.1).

Useful resources: