---
title: Making Your Notes Field Required in Shopify
description: "Often with store pickup or local delivery customers need to add notes but forget. ## Step 1 – Open the right file in your theme. 1. In Shopify admin go to **Online Store → Themes**. 2. On your **“Latest” /…"
url: "https://roseperl.com/Help/making-your-notes-field-required-in-shopify/"
updated: "2025-12-01"
category: RP ProPickup Local Pickup and Delivery
---

# Making Your Notes Field Required in Shopify

Often with store pickup or local delivery customers need to add notes but forget.

## Step 1 – Open the right file in your theme.

1. In Shopify admin go to **Online Store → Themes**.
2. On your **“Latest” / Current theme**, click **… → Edit code**.
3. In the left sidebar, under **Sections**, open:

`main-cart-footer.liquid`
or, if you don’t see that, open `main-cart-items.liquid`.

Dawn v15+ usually puts the **cart note** in `main-cart-footer.liquid`.

---

## Step 2 – Give the note field an ID (if it doesn’t have one)

Inside `main-cart-footer.liquid`, look for something like this:

```
<textarea   name="note"   ... >   {{ cart.note }} </textarea>
```

Change it to:

```
<textarea   id="CartSpecialInstructions"   name="note"   {{ block.shopify_attributes }} >   {{ cart.note }} </textarea>
```

If there’s already an `id` (like `Cart-note`), you can keep it, just remember what it is and use that in the script.

---

## Step 3 – Add an error message container

Right *under* that `<textarea>`, add:

```
<div id="CartNoteError"      style="display:none; color:red; font-size:0.9rem; margin-top:0.25rem;">   Please enter a note before continuing to checkout. </div>
```

You can style that with theme classes later; this just makes it work.

---

## Step 4 – Add the validation script in the same section

Scroll to the **bottom of `main-cart-footer.liquid`**, and just before the closing `{% schema %}` (or at the bottom if there’s no schema), paste this:

```
<!--RP Tech Support - Added Required Fields -->
```

```
<script>  document.addEventListener('DOMContentLoaded', function () {    var noteField = document.getElementById('Cart-note');    var errorEl   = document.getElementById('CartNoteError');    if (!noteField || !errorEl) return;    function showError(message) {      errorEl.textContent = message;      errorEl.style.display = 'block';    }    function hideError() {      errorEl.style.display = 'none';    }    var checkoutButtons = document.querySelectorAll(      'button[name="checkout"], button[id="checkout"], button[type="submit"][name="checkout"]'    );    checkoutButtons.forEach(function (btn) {      // NOTE: third argument "true" = capture phase      btn.addEventListener('click', function (event) {       var value = noteField.value.trim();        if (!value) {          // Block default form submit          event.preventDefault();          // Block any other click handlers on this button          event.stopImmediatePropagation();          showError('Please enter a note before continuing to checkout.');          noteField.focus();        } else {          hideError();          // If valid, do NOT preventDefault — default submit + other JS still run        }      }, true);    });    noteField.addEventListener('input', function () {      if (noteField.value.trim()) {        hideError();      }    });  });</script>
```

That will:

- Block checkout when the cart note is empty.
- Show a red message under the note.
- Clear the message as soon as the customer starts typing.

---

## Step 5 – Test in the theme editor

1. In **Online Store → Themes**, click **Customize** on your current theme.
2. Use the top dropdown to go to the **Cart page**.
3. Try:
   - Leaving the note blank → click **Checkout** → you should see the error and stay on the cart.
   - Typing something → click **Checkout** → you should go to Shopify Checkout.

---

## If you’re using the cart drawer too

The above only enforces it on the **cart page**. If your theme uses the **cart drawer**, and you want to force notes there too, you’ll need a similar script in `cart-drawer.liquid` targeting that drawer’s textarea and checkout button.

If you paste:

- A small snippet of your `main-cart-footer.liquid` around the note field, or
- A screenshot of your cart section in the theme editor,

---

## Update to Only Force the Note for Zero Dollar Items

Here is a Nice tweak 👌 — we’ll only force the note **if any cart line is free (0.00)**.

We’ll use Liquid to detect free items, then JS to enforce the note *only* in that case.

---

## 1️⃣ Add a “has free item” flag in `main-cart-footer.liquid`

In **Edit code → Sections → `main-cart-footer.liquid`**, somewhere **above your `<textarea>` or above the script**, add this Liquid snippet:

```
{%- assign has_free_item = false -%} {%- for item in cart.items -%}   {%- if item.final_line_price == 0 -%}     {%- assign has_free_item = true -%}   {%- endif -%} {%- endfor -%}  <div   id="CartHasFreeItem"   data-has-free-item="{{ has_free_item }}"   style="display:none;" ></div>
```

- `item.final_line_price == 0` checks for any line whose total is 0 (e.g. freebies, 100% discounts).
- We store that as `data-has-free-item="true"` or `"false"`.

Leave that div hidden; it’s just for JS.

---

## 2️⃣ Keep the note + error message as before

Make sure your note textarea and error container look like this (or similar):

```
<textarea   id="CartSpecialInstructions"   name="note"   {{ block.shopify_attributes }} >   {{ cart.note }} </textarea>  <div id="CartNoteError"      style="display:none; color:red; font-size:0.9rem; margin-top:0.25rem;">   Please enter a note before continuing to checkout. </div>
```

(If you already added this from the previous step, you’re good.)

---

## 3️⃣ Replace the old script with this one

Still in **`main-cart-footer.liquid`**, at the **bottom of the file** (before `{% schema %}`), **remove the previous script I gave you** and paste this updated version:

```
<script>  document.addEventListener('DOMContentLoaded', function () {    var noteField = document.getElementById('Cart-note');    var errorEl   = document.getElementById('CartNoteError');    if (!noteField || !errorEl) return;    function showError(message) {      errorEl.textContent = message;      errorEl.style.display = 'block';    }    function hideError() {      errorEl.style.display = 'none';    }    var checkoutButtons = document.querySelectorAll(      'button[name="checkout"], button[id="checkout"], button[type="submit"][name="checkout"]'    );    checkoutButtons.forEach(function (btn) {      // NOTE: third argument "true" = capture phase      btn.addEventListener('click', function (event) {        var flagEl = document.getElementById('CartHasFreeItem');        var hasFreeItem =          flagEl && flagEl.dataset.hasFreeItem === 'true';        // If no free items, don't enforce; let other JS do its thing        if (!hasFreeItem) {          hideError();          return;        }        var value = noteField.value.trim();        if (!value) {          // Block default form submit          event.preventDefault();          // Block any other click handlers on this button          event.stopImmediatePropagation();          showError('Please enter a note before continuing to checkout.');          noteField.focus();        } else {          hideError();          // If valid, do NOT preventDefault — default submit + other JS still run        }      }, true);    });    noteField.addEventListener('input', function () {      if (noteField.value.trim()) {        hideError();      }    });  });</script>
```

## What this does now

- **If no line item is free (0.00)** → checkout works normally, even with an empty note.
- **If at least one line item is free** → note becomes required; empty note blocks checkout and shows the red message.

---

## 4️⃣ Quick test checklist

On the **cart page**:

1. **No free items** in cart → leave note blank → click **Checkout** → you *should* go through.
2. Add a **free item** (or discount to 100% off) → leave note blank → click **Checkout** → you should see the error and stay on the cart.
3. With free item in cart, **fill in note** → click **Checkout** → should go through.

---

# Item that are Zero vs Total line being Zero

If you want it to be “price 0 per unit” instead of “line total 0”, here is the tweak the Liquid to check `item.final_price` instead of `item.final_line_price`.

You only need to change the **Liquid flag block**; the JS stays the same.

---

## 1️⃣ Update the “has free item” flag to use unit price

In `main-cart-footer.liquid`, replace the previous flag block with this:

```
{%- assign has_free_item = false -%} {%- for item in cart.items -%}   {%- if item.final_price == 0 -%}     {%- assign has_free_item = true -%}   {%- endif -%} {%- endfor -%}  <div   id="CartHasFreeItem"   data-has-free-item="{{ has_free_item }}"   style="display:none;" ></div>
```

- Now it checks `item.final_price == 0` → **per-unit** final price is free, even if quantity > 1.

Leave your `textarea`, error div, and script exactly as they were from the last step:

```
<textarea   id="CartSpecialInstructions"   name="note"   {{ block.shopify_attributes }} >   {{ cart.note }} </textarea>  <div id="CartNoteError"      style="display:none; color:red; font-size:0.9rem; margin-top:0.25rem;">   Please enter a note before continuing to checkout. </div>
```

And the script:

```
<script>   document.addEventListener('DOMContentLoaded', function () {     var noteField = document.getElementById('CartSpecialInstructions');     var errorEl   = document.getElementById('CartNoteError');      if (!noteField || !errorEl) return;      var checkoutButtons = document.querySelectorAll(       'button[name="checkout"], button[id="checkout"], button[type="submit"][name="checkout"]'     );      function showError(message) {       errorEl.textContent = message;       errorEl.style.display = 'block';     }      function hideError() {       errorEl.style.display = 'none';     }      checkoutButtons.forEach(function (btn) {       btn.addEventListener('click', function (event) {         var flagEl = document.getElementById('CartHasFreeItem');         var hasFreeItem =           flagEl && flagEl.dataset.hasFreeItem === 'true';          // If there are no free items by unit price, don't enforce the note         if (!hasFreeItem) {           return;         }          var value = noteField.value.trim();          if (!value) {           event.preventDefault();           showError('Please enter a note before continuing to checkout.');           noteField.focus();         } else {           hideError();         }       });     });      // Clear error while typing     noteField.addEventListener('input', function () {       if (noteField.value.trim()) {         hideError();       }     });   }); </script>
```

---

## 2️⃣ Quick sanity check

- Item at **$0.00 per unit** (no matter the quantity) → note required.
- Discounted to **$0.00 per unit** via automatic discount/code → note required.
- All items have unit price > 0 → note optional.
