How do I add line item properties in Liquid without an app?
Add an input to product-form.liquid (or your theme's equivalent) with the name properties[Field Name]. The customer's input becomes a line-item property when they add to cart. Cart and email templates that include the standard properties loop will display it. Total code: 3-5 lines. Total setup: 5 minutes. Cost: free. Downsides: no live preview, no image validation, no per-field pricing add-on, no mobile UI polish — for those, use Print It My Way.
Step-by-step setup
- Add input to product-form.liquid. Use name='properties[Field Name]' syntax.
- Add validation attributes. maxlength, required, pattern — HTML5 attributes work.
- Verify cart-item.liquid renders properties. Check the {% for property in item.properties %} loop.
- Test add-to-cart, cart page, checkout, order confirmation. Property should appear on all four.
Step 1 — Add the input
Open sections/main-product.liquid or snippets/product-form.liquid. Inside the form, before the add-to-cart button, add:
<div class="product-form__personalization">
<label for="engraving">Engraving text (max 20 chars)</label>
<input
id="engraving"
type="text"
name="properties[Engraving text]"
maxlength="20"
placeholder="Enter name"
/>
</div>
Multiple fields
Add as many properties[...] inputs as you need:
<input name="properties[Engraving text]" type="text" maxlength="20">
<input name="properties[Font]" type="hidden" value="Playfair Display">
<label>
<input name="properties[Gift wrap]" type="checkbox" value="Yes">
Add gift wrap (+$5)
</label>
Step 2 — Cart display
Verify sections/main-cart-items.liquid and cart-drawer.liquid include the properties loop:
{% for property in item.properties %}
{% assign first_char = property.first | slice: 0, 1 %}
{% if property.last != blank and first_char != '_' %}
<dt>{{ property.first }}:</dt>
<dd>{{ property.last }}</dd>
{% endif %}
{% endfor %}
Step 3 — Validation
HTML5 attributes handle basic validation: required, maxlength, minlength, pattern. For richer validation (profanity blocklist, regex, image DPI), you'd need JavaScript — at that point an app makes more sense.
Step 4 — Pricing (limitations)
Native Liquid can't add a fee to a cart line. If "gift wrap" costs $5, either: (a) create a separate $5 fee product and add it to cart with a Liquid form action="/cart/add", or (b) use a product options app with Cart Transform for a clean single-line fee. Option (a) creates cart clutter; (b) is why apps exist.
When to graduate to an app
Move to Print It My Way (Free plan) when you need: live preview, image upload, per-character pricing, conditional logic, mobile-optimized field styling, or 3+ fields per product. The Liquid approach is fine for one text field on one product.
Skip the Liquid work
Print It My Way handles input + cart + checkout + email without any theme editing.
Install Print It My Way — Free Complete line-item properties guide →Frequently asked questions
Can I add line-item properties without an app?
Yes for one field. Add an input to product-form.liquid with name='properties[Field Name]'. For more than one field or any pricing, an app is cleaner.
Do I need to edit cart.liquid too?
Only if your theme's cart doesn't display properties by default (most modern themes do). Check for the {% for property in item.properties %} loop.
How do I make a line-item property required?
Add the HTML5 required attribute: .
Can I add pricing via Liquid?
Not to a line-item property directly. Cart Transform (Plus API) or an options app can add per-property fees. Native Liquid can only add a separate fee product.
Do line-item properties break Shopify's Buy X Get Y or discount codes?
No. Discounts apply to the line's base price + Cart Transform surcharges. Properties themselves are just metadata.