> Deprecated:
> `checkout.liquid` is now unsupported for the Information, Shipping, and Payment checkout steps. 'checkout.liquid', additional scripts, and script tags are deprecated for the **Thank you** and **Order status** pages and will be sunset on August 28, 2025.

> Stores that currently use `checkout.liquid` for the **Thank you** and **Order status** pages need to [upgrade to Checkout Extensibility](https://www.shopify.com/plus/upgrading-to-checkout-extensibility) before the deadline. [Shopify Scripts](/docs/api/liquid/objects#script) will continue to work alongside Checkout Extensibility until August 28, 2025.

> Learn [how to build checkout extensions](/docs/apps/build/checkout/technologies) that extend the functionality of Shopify checkout.




<!---->

> Caution:
> Before you make changes to your checkout, it's recommended that you back up the current version of the code in your `checkout.liquid` file. To learn more about backing up your theme, refer to [Downloading themes](https://help.shopify.com/manual/online-store/themes/managing-themes/downloading-themes) or [Duplicating themes](https://help.shopify.com/manual/online-store/themes/managing-themes/duplicating-themes).

If you're on Shopify Plus, then you can get access to the `checkout.liquid` layout. However, if you make changes to this layout, then you'll need to [manually upgrade it](https://help.shopify.com/en/manual/checkout-settings/checkout-upgrade) whenever Shopify releases an upgrade.

## Document Object Model (DOM) dependency

One of the biggest considerations to make when implementing checkout modifications is how DOM-dependent your code is. As Shopify releases checkout upgrades, the content output by the Liquid drops in `checkout.liquid`, and in some cases by the `checkout.liquid` content itself, is updated. This means that if your customizations depend on that content, then they could break with new upgrades. It’s always best to minimize DOM dependency to reduce future support debt for your team.

> Tip:
> Other than adding content only outside of the Liquid drops, the most DOM-independent method for accessing elements is to reference `data` and `name` attributes, as these are less likely to be changed across upgrades.

## Add custom code

When making changes, you should keep all of the relevant code for a specific customization in a single snippet. This reduces the risk of conflict with other code, and generally makes the code easier to read.

Also, any time that a change is made, it's recommended that you place a comment at the beginning of the change noting who made it, and when.

<p>
<div class="react-code-block" data-preset="file">
<div class="react-code-block-preload ThemeMode-dim">
<div class="react-code-block-preload-bar "></div>
<div class="react-code-block-preload-placeholder-container">
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>

</div>
</div>

<script data-option="filename" data-value="Example"></script>

<script type="text/plain" data-language="liquid">
RAW_MD_CONTENT{% comment %} Added by Name from Company on September 21 2018 {% endcomment %}
END_RAW_MD_CONTENT</script>

</div>
</p>


## Add killswitches

When customizing `checkout.liquid`, you're more likely to run into issues or conflicts in the checkout, possibly preventing sales, so it's a good idea to wrap your customizations in a killswitch (a theme setting). This allows you to temporarily disable the customization to get the checkout functioning quickly, which gives you time to troubleshoot issues.

## General customization approach

In general, the approach for making customizations is the following:

- Create a killswitch theme setting
- Create a snippet to host your customization
- Include your snippet, wrapped in your killswitch, in `checkout.liquid`

The following examples show a killswitch theme setting and a snippet inclusion wrapped in a conditional based on the killswitch:

<p>
<div class="react-code-block" data-preset="file">
<div class="react-code-block-preload ThemeMode-dim">
<div class="react-code-block-preload-bar "></div>
<div class="react-code-block-preload-placeholder-container">
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>

</div>
</div>

<script data-option="filename" data-value="config/settings_schema.json"></script>

<script type="text/plain" data-language="json">
RAW_MD_CONTENT{
  "type": "checkbox",
  "id": "checkout_customization",
  "label": "Enables a checkout customization"
},
END_RAW_MD_CONTENT</script>

</div>
</p>


<p>
<div class="react-code-block" data-preset="file">
<div class="react-code-block-preload ThemeMode-dim">
<div class="react-code-block-preload-bar "></div>
<div class="react-code-block-preload-placeholder-container">
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>
<div class="react-code-block-preload-code-container">
<div class="react-code-block-preload-codeline-number"></div>
<div class="react-code-block-preload-codeline"></div>
</div>

</div>
</div>

<script data-option="filename" data-value="layout/checkout.liquid"></script>

<script type="text/plain" data-language="liquid">
RAW_MD_CONTENT
{% comment %}Added by Name at Company on September 21, 2018{% endcomment %}
{% if settings.checkout_customization %}
  {% render 'checkout-customization' %}
{% endif %}

END_RAW_MD_CONTENT</script>

</div>
</p>


In your snippet, you can do the following:

- Use the checkout's version of jQuery
- Watch for the `page:load` and `page:change` events to set up your customization
- Scope your customization to the appropriate step or page by referencing the following objects:
  - `Shopify.Checkout.step`
  - `Shopify.Checkout.page`
  - `Shopify.Checkout.OrderStatus`

```javascript
(function($) {
  $(document).on("page:load page:change", function() {
    if (Shopify.Checkout.step === "contact_information") {
      // Add content
    }
  });
})(Checkout.$);
```

## Form submit

Many checkout customizations require validating data before allowing the customer to move to the next step. Due to the functionality around the main form submit button, the easiest approach is watch for the `click` event on this button, rather than the `submit` field on the form. You should also watch for the use of the enter key and re-route that functionality into a `click` event on the submit button.

> Caution:
> All selectors used in the snippet below are placeholders. You'll need to decide on the selector you want to use. Try to avoid [DOM dependency](#document-object-model-dom-dependency).

```javascript
(function($) {
  $(document).on("page:load page:change", function() {
    if (Shopify.Checkout.step === "contact_information") {
      $("DEFINE_YOUR_SUBMIT_BUTTON_SELECTOR").on("click", function(e) {
        e.preventDefault();

        if (data is valid) {
          $("DEFINE_YOUR_MAIN_FORM_SELECTOR").submit();
        } else {
          // Show an error
        }
      });

      $("DEFINE_YOUR_MAIN_FORM_SELECTOR").on("keyup", function(e) {
        if (e.keycode === 13) {
          e.preventDefault();
          $("DEFINE_YOUR_SUBMIT_BUTTON_SELECTOR").trigger("click");
        }
      });
    }
  });
})(Checkout.$);
```

## Common customizations

The following examples are commonly requested customizations. They all use the [general customization approach](#general-customization-approach) as a starting point.

### Block the use of specific characters in address fields

To block the use of specific characters in address fields, you need to consider the following cases:

1. Updates to the associated address fields, such as the `blur` event.

2. The [form submit](#form-submit) event.

For each of these cases, execute your validation. For example, you could compare any field values with a Regular Expression (Regex). If the data isn't valid, you can show an error and prevent the default functionality.

### Limit the number of characters in address fields

To limit the number of characters in address fields, add a `maxlength` attribute to any associated fields, as shown in the following example.

> Note:
> The selector used below is a placeholder. You'll need to decide on the selector you want to use. Try to avoid [DOM dependency](#document-object-model-dom-dependency).

```javascript
$("DEFINE_YOUR_FIELD_SELECTOR").attr("maxlength", your_value);
```

The `maxlength` attribute only prevents additional characters from being entered. To ensure a good user experience, you should add a message that appears when a customer hits the character limit.

### Add a required Terms of Service checkbox

To add a required checkbox for agreeing to Terms of Service, create a checkbox on the page, then follow the [form submit](#form-submit) event to check whether the checkbox has been checked before allowing the customer to proceed. It's also a good idea to use a [checkout attribute](/docs/storefronts/themes/architecture/layouts/checkout-liquid#capture-checkout-attributes) to save the value of the checkbox.