Build Forms on Shopify: How to Use Liquid to Build Robust Forms for Shopify Themes

build forms on shopify

[November 2022 Update] Want an easier way to add forms to a store?

Shopify Forms is now available—a free email capture app that works seamlessly with discounts, Shopify Email, marketing automations, and more. Set up on-brand forms, select when and where they'll show up, and track their performance in Shopify.

Install app

If you build forms on Shopify, you know that they’re used across a range of touchpoints on Shopify stores, from customer registration, to blog commenting, to contacting merchants, and even adding product variants to the cart. Since forms carry a lot of responsibility for connecting your client with their customers, it’s crucial that these components are robust and user-friendly.

It’s easy to overlook the importance of forms in favor of more dynamic components of your client’s online stores like Shopify metafields. But in terms of functionality, forms play a very important role in how customers interact with a store.

"Forms play a very important role in how customers interact with a store."

Creating forms can often be repetitive, and mistakes can occur when building them from scratch. Thankfully, there are a number of Liquid elements that make working with forms easier and more reliable by automatically generating the code necessary for transferring data to the correct endpoint. 

In this article, we look at how Liquid can be leveraged to simplify the process when you build forms on Shopify by generating input elements, identifying errors, and outputting feedback to customers. We’ll also be looking at which form types developers have access to when creating different forms.

What is the form tag?

The form Liquid tag generates an HTML <form> element along with the necessary inputs to send submitted data to a specific endpoint. Using this tag automates the process of assigning actions and values when building different types of forms on Shopify pages.

This form tag allows developers to quickly and reliably add forms to their projects, without having to write the full code to describe which action to take, or which endpoint the form will be targeting. This means it saves time and reduces the potential for human error when building forms for logging in, commenting on blog posts, and contacting merchants.

When the form tag is used with a specified type, an HTML <form> element is created along with input elements that are used by the endpoint to decide what to do with the submitted data on what exact action to take. Depending on which form type is being implemented, a different set of inputs will be generated to perform the required action.

The automatically created input fields are intended to connect with Shopify’s server endpoints, and there are no input fields created by the form tag that users would interact with. This means developers will manually add input fields for customer emails or passwords, while the tag takes care of sending data to Shopify’s servers.

You might also like: How to Display Price Ranges on Shopify Collection Pages.

An example of the form tag

As we’ve learned, the form tag is a more reliable alternative to building a form in HTML. For example, if you were creating a customer login form, without using the form tag, you’d need to create something like the following:

<form accept-charset="UTF-8" action="" id="customer_login" method="post">
<input name="form_type" type="hidden" value="customer_login" />
<input name="utf8" type="hidden" value="✓" />
<!--code for input fields and labels-->

The form tag can take care of all the above code with this simplified markup:

{% form 'customer_login' %}
<!--code for input fields and labels-->
{% endform %}

We can see from this example that the opening form tag also includes a “type,” which in this case is customer_login. There are 13 different form types that generate specific <form> and <input> elements for each particular purpose. We’ll be looking at the currently available form types later.

While the form tag does create the necessary <form> and <input> sending data to a specific endpoint, we’ll need to create the input elements that your client’s customers will be interacting with.

For example, to make our customer login form functional, we’ll need to create fields to input an email address, password, and submit button. Once these are added into the form tags, it should appear like this:

If we view this form from the front-end of the online store we should see this:

build forms on shopify: log in working model

You can view a full working model of a customer login form on our Liquid Code Examples, and even use this as a basis for your own theme builds.

Additional parameters

In some cases, additional parameters need to be added within the form tag to target a specific object. For example, the form used to submit a comment on a blog article requires the type of new_comment and needs an article object as a parameter:

{% form 'new_comment', article %}
<!--code for input fields and labels-->
{% endform %}

This will output to:

<form accept-charset="UTF-8" action="/blogs/news/10582441-my-article/comments"
class="comment-form" id="article-10582441-comment-form" method="post">
<input name="form_type" type="hidden" value="new_comment" />
<input name="utf8" type="hidden" value="✓" />
<!--code for input fields and labels-->

In this example, the article parameter will allow the form to associate the new comment with the correct blog post. Forms for products, customer addresses, and new article comments all require additional parameters.

The different Liquid form types

There are 13 different Liquid form types for specific touchpoints where customers would be interacting with a client’s store or submitting data. As we’ve seen from our customer registration example, to generate a form, the form tag requires a type.

"There are 13 different Liquid form types for specific touchpoints where customers would be interacting with a client’s store or submitting data."

These predefined form types are:

  • activate_customer_password
  • contact
  • currency
  • customer
  • create_customer
  • customer_address
  • customer_login
  • guest_login
  • new_comment
  • product
  • recover_customer_password
  • reset_customer_password
  • storefront_password

Examples of each of these forms and any additional required parameters are demonstrated in our Help Center.

Using conditional logic within forms

Certain types of forms may require extra functionality, like resetting a forgotten password, or displaying an error when invalid data is submitted. We can use control flow tags to set up rules that will display content when a specific event occurs, such as displaying an error message when an email address is incorrectly entered.

The Liquid object form.errors and the Liquid filter default_errors are very helpful in cases where data is not submitted successfully through a form, as they allow you to display default error messages.

The form.errors object will output or return an array of strings if a form was not submitted successfully. The strings returned depend on which fields of the form were left empty or contained errors. Possible values which can be returned are:

  • author
  • body
  • email
  • form

This object allows us to identify and output which part of a form was not entered correctly. If we want to display what type of error a customer has made, we could set up an iteration for loop like this:

{% for error in form.errors %}
{{ error }}
{% endfor %}

In the case above, if a customer entered an invalid email address, the value email would be outputted. Now we can use this returned output and apply the default_errors filter to automatically generate a predefined error message.

The default_errors filter will return a specific message based on the string returned by the form.errors object. To see this in practice, we would use control-flow tags to create the following if statement within our {% form %} tags:

{% if form.errors %}
{{ form.errors | default_errors }}
{% endif %}

Now, if a user entered an invalid email address, they would see the following message:

Please enter a valid email address.

Adding these conditional rules to your custom theme builds are crucial to ensure that your client’s customers see the correct feedback if they have entered invalid data. In this way, Liquid can be leveraged to provide visible and specific error messages to your client’s customers at the right time.

You might also like: How to Customize the img Element in Shopify Themes.

Form and function

Now that you’ve seen how Liquid objects, tags, and filters can be implemented together to create robust forms, you can extend the functionality when you build forms on Shopify by adding custom fields based on your client’s requirements, or modifying the form attributes.

However you adjust or iterate on how you build and design your forms, making use of the relevant Liquid elements will ensure your forms are robust and consistent. Hopefully with the help of this article, you will be more familiar with how Liquid can improve your forms and theme projects.

How have you used forms in your projects? Let us know in the comments below!

Grow your business with the Shopify Partner Program

Learn more