Skip to main content

Caching FormsImproved in 5.0+

Forms and pages can be cached in a variety of ways, but you need to ensure that your CSRF token is being refreshed in order for the form to continue working.

Here are some solutions, depending on your caching approach:

Craft Caching

When using simple Twig-based Craft Caching, you'll need to make sure that you are refreshing the CSRF token.

There are two approaches you can take:

The simplest approach you can take is enabling Craft's asyncCsrfInputs setting. It will automatically take care of the CSRF token for you and you don't need to do anything else.Recommended

Template Code

{% cache %}
{{ freeform.form("myFormHandle").render }}
{% endcache %}

Craft Config

->asyncCsrfInputs(true)

Static Caching / Blitz

When using full static page caching with services like CloudFlare, Craft Cloud or the Blitz Craft plugin, you'll need to make sure that you are refreshing the CSRF token.

There are a few different approaches you can take:

If your form is a single-page form, you can use Craft's asyncCsrfInputs setting. It will automatically handle the CSRF token for you, and you won't need to do anything else.Recommended

Craft Config

->asyncCsrfInputs(true)

Stripe Payment Forms

When using the built-in Stripe integration, Freeform will trigger Payment Intent requests automatically upon page load. These requests use the initial form data, meaning the original CSRF token.

The assumption is that payment forms should never be cached, so if your form has a Stripe integration enabled and you are using Blitz caching and refreshing your CSRF tokens, we suggest injecting your payment form into your template using Blitz dynamic content or Sprig.

There is then no need to refresh CSRF tokens as the dynamic content is injected after the page loads. Otherwise, you risk a 400 Bad Request - Unable to verify your data submission error.