Skip to content

Instantly share code, notes, and snippets.

@minanagehsalalma
Created February 27, 2026 09:18
Show Gist options
  • Select an option

  • Save minanagehsalalma/b80a4eb5e1ec6baa27ce2d3aea3fd439 to your computer and use it in GitHub Desktop.

Select an option

Save minanagehsalalma/b80a4eb5e1ec6baa27ce2d3aea3fd439 to your computer and use it in GitHub Desktop.
How to Force Submit a React Form with reCAPTCHA Enterprise via the Browser Console

How to Force Submit a React Form with reCAPTCHA Enterprise via the Browser Console

A step-by-step guide for submitting a React form when the submit button is disabled or blocked.


Step 1: Enable the Disabled Button (Optional)

If the submit button has a disabled attribute, remove it:

document.querySelector('[data-test="form-submit"]').removeAttribute('disabled');

Note: On React apps, this alone won't trigger submission — React manages its own internal state separately from the DOM.


Step 2: Check What's Blocking Submission

Validate all form fields to find any empty or invalid ones:

document.querySelectorAll('form input, form textarea').forEach(el => {
  console.log(el.name, el.value, el.checkValidity(), el.validationMessage);
});

Look for any field with an empty value — a common culprit is g-recaptcha-response.


Step 3: Identify the reCAPTCHA Version

Check what's available on the grecaptcha global:

console.log(Object.keys(grecaptcha));
  • If you see ready, execute, etc. → it's reCAPTCHA v2/v3
  • If you see enterprise → it's reCAPTCHA Enterprise (continue below)

For Enterprise, check available methods:

console.log(Object.keys(grecaptcha.enterprise));

Step 4: Get the Site Key

Find the reCAPTCHA site key from the page:

const siteKey = document.querySelector('[data-sitekey]')?.dataset.sitekey 
  || document.querySelector('iframe[src*="recaptcha"]')?.src.match(/[?&]k=([^&]+)/)?.[1];
console.log('site key:', siteKey);

Step 5: Generate a reCAPTCHA Token

Use the site key to generate a valid token:

grecaptcha.enterprise.ready(async () => {
  const token = await grecaptcha.enterprise.execute('YOUR_SITE_KEY', { action: 'submit' });
  console.log('token:', token);
});

Step 6: Inject the Token and Submit via React Fiber

React forms don't respond to native DOM events, so you need to access React's internal fiber tree to call the onSubmit handler directly. Inject the token and trigger submission together:

grecaptcha.enterprise.ready(async () => {
  const siteKey = 'YOUR_SITE_KEY';
  const token = await grecaptcha.enterprise.execute(siteKey, { action: 'submit' });

  // Inject the reCAPTCHA token into the hidden field
  document.querySelector('[name="g-recaptcha-response"]').value = token;

  // Trigger React's onSubmit handler via the fiber tree
  const form = document.querySelector('form');
  const fiberKey = Object.keys(form).find(k =>
    k.startsWith('__reactFiber') || k.startsWith('__reactInternalInstance')
  );
  let node = form[fiberKey];
  while (node) {
    const props = node.memoizedProps || node.pendingProps;
    if (props && props.onSubmit) {
      props.onSubmit({
        preventDefault: () => {},
        stopPropagation: () => {},
        nativeEvent: new Event('submit'),
        target: form,
        currentTarget: form,
        bubbles: true,
        isTrusted: true
      });
      break;
    }
    node = node.return;
  }
});

Step 7: Verify in the Network Tab

Open DevTools → Network tab before running the script. After running, look for:

  • A GET request to recaptcha_en.js or similar → reCAPTCHA verified ✅
  • A POST/fetch request to the form endpoint → form submitted ✅

Both returning 200 means your form was submitted successfully.


Notes

  • reCAPTCHA tokens expire after ~2 minutes. Run the full Step 6 script in one go — don't generate the token separately and paste it later.
  • This technique works because React stores its event handlers in a virtual fiber tree, not as standard DOM event listeners.
  • If the server returns an error despite a 200 network status, the issue is server-side (e.g., session expired, missing auth header).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment