Skip to main content

CAPTCHA

Shopify uses hCaptcha to help prevent spam through customer, contact, and blog comment forms.

Initially, hCaptcha analyzes website visitor behavior to provide a score indicating the likelihood of the visitor being a bot, without requiring the visitor to solve an interactive challenge.

If the assessment result is suspicious enough, or if too many requests are made within a short period of time, then the visitor is redirected to the /challenge page to perform an interactive challenge for further assessment.

Merchants are able to disable hCaptcha functionality on the Online Store > Preferences page in the Shopify admin.


Anchor to How CAPTCHA is included in themesHow CAPTCHA is included in themes

The necessary code for the CAPTCHA functionality is included through the content_for_header object. This means that if a merchant has CAPTCHA enabled, but the content_for_header object isn't present, then the CAPTCHA functionality won't be present.

The CAPTCHA functionality is initialized based on the presence of customer, contact, and blog comment forms, and by default is triggered when the forms are interacted with. For example, the functionality is triggered when a user clicks a text field of an associated form.

These forms are identified based on the action attribute of the form, as well as specific input attributes:

Form typeForm action attributeInput attributes (included on a single input)
CustomerContains /account

name="form_type"

One of the following, depending on the form:

  • value="customer_login"
  • value="create_customer"
  • value="recover_customer_password"
ContactContains /contact

name="form_type"

One of the following, depending on the form:

  • value="contact"
  • value="customer"
BlogContains /blogs
  • name="form_type"
  • value="new_comment"
Tip

The form action attribute and associated input attributes are output by default when using a relevant Liquid form tag. If your theme uses custom forms, then make sure that the above attributes are included so that your forms are compatible with CAPTCHA functionality.

Example

<form action="/account/login" ...>
<input type="hidden" name="form_type" value="customer_login" />
...
</form>

In addition to triggering the CAPTCHA functionality on user interaction, a CAPTCHA logo is added to the bottom right corner of the page to notify visitors of the behavior analysis. You can opt to show a text disclaimer with the form instead.


Anchor to Show a text disclaimerShow a text disclaimer

If CAPTCHA is enabled and CAPTCHA has loaded, then the CAPTCHA logo appears in the bottom right corner of any associated pages. You can choose to show a text disclaimer with the form, rather than this logo.

To do this, you need to include the following code within any forms you wish to change this for:

{{ 'shopify.online_store.spam_detection.disclaimer_html' | t }}

Anchor to Advanced: Forcing CAPTCHA wire up to a formAdvanced: Forcing CAPTCHA wire up to a form

Caution

To keep your integration compatible with Shopify's form abuse protection mechanisms, avoid working directly with the underlying CAPTCHA libraries. For example, don't call methods on window.hCaptcha. Instead, use the following supported methods.

In some scenarios, it might be necessary to force CAPTCHA wire up to a form. For example, the form might be indirectly populated and submitted, so the default behavior of wiring CAPTCHA on user interaction never happens. In these cases, you have the following options:

Anchor to Wire up using a data attributeWire up using a data attribute

Adding the data-shopify-captcha attribute with a value of true causes CAPTCHA to wire up to the form immediately when the page loads.

Data attribute example (Liquid)

{%- form 'customer_login', data-shopify-captcha: "true" -%}

Data attribute example (HTML)

<form data-shopify-captcha="true" action="/account/login" ...>
<input type="hidden" name="form_type" value="customer_login" />
...
</form>

Anchor to Wire up using JavaScriptWire up using JavaScript

Alternatively, CAPTCHA can be wired up to a form using JavaScript. window.Shopify.captcha.protect should be invoked with the form that you want to wire up as the first argument, and with an optional callback function as the second argument. If provided, the callback is invoked after CAPTCHA is ready.

This is primarily useful in cases where you programmatically manipulate and submit the form in response to other user action.

JavaScript example

const myForm = document.querySelector('#my-form');
window.Shopify.captcha.protect(myForm, () => {
myForm.elements["contact[email]"].value = 'test@example.com';
myForm.submit();
});

Anchor to Verifying that hCaptcha is wired upVerifying that hCaptcha is wired up

You can verify that hCaptcha is correctly wired to your form by using your browser's network dev tools while the form is being submitted.

  1. Open dev tools on the Network tab.
  2. Fill in and submit the form.
  3. In the browser's dev tools, inspect the payload of the POST request to the server.
  4. Ensure that the h-captcha-response field is present and contains data.

  • Ensure that your theme includes Liquid's content_for_header object in layouts that contain forms that require hCaptcha. Ensure that no code modifies or changes this object.

  • If you want your form to be automatically wired up, ensure that its markup is correct, with the requisite action attribute and corresponding form_type child input. For more information, refer to how CAPTCHA is included in themes.

  • By default, hCaptcha is initialized on the DOMContentLoaded event, but is only wired up when the user interacts with the form. If you're building or submitting forms programmatically or adding them to the DOM after the DOMContentLoaded event has been emitted, then you might need to use window.Shopify.captcha.protect to ensure that CAPTCHA executes correctly.

  • Some third-party applications may block hCaptcha resources, or otherwise manipulate the DOM in ways that cause hCaptcha to not wire up correctly. Such apps could be focused on improving page load metrics or managing GDPR consent. Consider temporarily disabling such apps while you debug. Often the apps have ignore lists that enable you to fix the issue after it's identified.


Was this page helpful?