Best practices for editing checkout.liquid

If you're on Shopify Plus, then you can edit the code for your checkout. However, if you make changes to your checkout code, then you need to upgrade your checkout.liquid template manually whenever Shopify makes an upgrade.

Adding custom code

When making changes it is good to keep all of the relevant code for a specific customization in a single snippet. Doing this cuts back the risk of conflict with other code and generally makes the code clearer to read.

Any time a change is made to a customization, it is recommended that a comment is placed at the beginning of the change. The comment should contain who made the change and when the change was made. For example:

{% comment %} Added by Name from Company on September 21 2018 {% endcomment %}

Document Object Model dependency

One of the biggest considerations to make when implementing checkout modifications is how Document Object Model (DOM) dependent your code is. As Shopify releases checkout upgrades, the content output by the Liquid variable calls in checkout.liquid (and in some cases the checkout.liquid content itself) is upgraded. This means that if your customizations depend on that content, then they might break as Shopify releases new upgrades. It’s always best to minimize DOM dependency as this can go a long way in cutting down on future support debt for your team.

There are various Liquid variable calls in checkout.liquid that output all of the checkout HTML/Content, so if you’re targeting an element that’s output by one of these variable calls, then your function could possibly break with a checkout upgrade. If you need to target an element with a Liquid variable call then it’s best to use that attribute as a selector. The data attributes can also be used, rather than a class or ID.

For example, when making changes using the Google Chrome inspect tool, the browser shows all the IDs and class names that relate to the visual changes being made. These do not necessarily relate directly to what is in the Liquid file, where variable calls are used. Directly copying edits from the inspect tool is therefore not recommended, as the IDs and classes don't always match what is rendered in the browser.

Kill switches

After adding in a snippet call to the customization, you can wrap all the snippet code in a single liquid conditional that is connected to a theme setting. This is a killswitch. If unforeseen conflicts arise with a customization, the code can be disabled through the theme setting. This removes all the code from the customization from the storefront but keeps the file within the theme to be edited later.

The following example shows killswitch code wrapped around snippet:

{% if settings.checkout_customization %}
<style>
  //Add styles
</style>

<div>
  //Add HTML content
</div>

<script>
  (function ($){
    ‘use strict’;
    //Add Javascript
  }(jQuery);
</script>
{% endif %}

The following example shows ‘killswitch’ theme setting code:

,
{
    "type": "checkbox",
    "id": "checkout_customization",
    "label": "Enables a checkout customization"
},

Capture and preserve cart attributes

When capturing checkout attributes you can capture them the same way as capturing cart attributes, which can be viewed in this document. To have an attribute passed through you will need to append the attribute input inside the form using javascript. This is because the main content form is output by the liquid drop and there is no direct access to it.

However, there is a difference in capturing the name attribute. While in a cart the code would be:

input type=”text” name="attributes[attribute name]">

Obtaining the same attribute in the checkout would require this code:

<input type=”text” name=”checkout[attributes][attribute name]”>

Something to note about this method is that if you capture an attribute in checkout, it will wipe out any existing attribute you have captured in the cart. To get around this, you can use the checkout.attributes liquid object which has the cart attribute value. Loop through them, and add them into the checkout as attribute inputs with value defined by the existing attribute data:

{% for attribute in checkout.attributes %}
<input type=”text” name=”checkout[attributes][{{ attribute.first }}]”
    value=”{{ attribute.last  }}” />
{% endfor %}

Ready to start selling with Shopify?

Try it free