ShipStation's packing slip editor now supports Liquid template language that lets you add dynamic logic to your packing slips. Liquid is a widely used, well-documented templating language created by Shopify, if you've customized Shopify email notifications before, the Liquid syntax will feel familiar. It's safe for customer-facing content and does not execute arbitrary code or access information outside of ShipStation.
With Liquid, you can show content conditionally, loop through order items, format values, and more. It allows for more template customization than using one-to-one substitutions like field replacements. You can use Liquid and Field Replacements in the same packing slip template. In general:
-
Use Field Replacements for simple value insertion, especially in the visual editor.
-
Use Liquid when you need conditions, loops, or value formatting in the HTML editor.
Liquid language has three main building blocks:
|
Type |
Syntax |
Function |
|---|---|---|
|
Objects |
{{ variable }} |
Outputs the referenced value. For example, {{ order_number }} will expose the order number the packing slip is being printed for. See the Variables section for more information on this function. |
|
Tags |
{% tag %} |
Controls logic (if, for, unless, etc) |
|
Filters |
{{ value | filter }} |
Transforms output before it's displayed |
A variable is a named placeholder like an order number, a recipient's name, or a ship date. With Liquid logic instead of typing that information manually, you reference the variable and Liquid fills it in automatically when the packing slip is generated. If you're used to ShipStation's Field Replacements like [Order Number], variables work the same way, Liquid just gives you more flexibility.
Variables in Liquid are wrapped in double curly braces: {{ variable_name }}. For example, {{ order_number }} might output 1042, and {{ recipient.name }} might output Jane Smith — depending on the order the packing slip is being printed for.
You can also pass a variable through a filter to transform it before it's displayed. For example {{ ship_date | date: "%B %d, %Y" }} takes the raw ship date value and formats it as April 09, 2026.
The following variables can be used when customizing your packing slips:
Order Variables
|
Variable |
Description |
|---|---|
|
{{ order_number }} |
Store order number |
|
{{ order_date }} |
Date the order was placed |
|
{{ order_total }} |
Total order value |
|
{{ payment_method }} |
Payment method |
|
{{ gift_message }} |
Gift message, if present |
Shipment Variables
|
Variable |
Description |
|---|---|
|
{{ tracking_number }} |
Shipment tracking number |
|
{{ carrier }} |
Carrier Name |
|
{{ service }} |
Shipping Service |
|
{{ ship_date }} |
Ship Date |
Recipient Variables
|
Variable |
Description |
|---|---|
|
{{ recipient.name }} |
Recipient Full Name |
|
{{ recipient.address1 }} |
Address line 1 |
|
{{ recipient.address2 }} |
Address line 2 |
|
{{ recipient.address3 }} |
Address line 3 |
|
{{ recipient.city }} |
City |
|
{{ recipient.state }} |
State/Province |
|
{{ recipient.zip }} |
ZIP / Postal Code |
|
{{ recipient.country }} |
Country |
Store Variables
|
Variable |
Description |
|---|---|
|
{{ store.name }} |
Store name |
|
{{ store.email }} |
Store contact email |
|
{{ store.phone }} |
Store phone number |
|
{{ store.website }} |
Store website URL |
|
{{ store.logo_url }} |
Store logo image URL |
Item Variables
|
Variable |
Description |
|---|---|
|
{{ item.name }} |
Item name / description |
|
{{ item.sku }} |
Item SKU |
|
{{ item.quantity }} |
Quantity ordered |
|
{{ item.price }} |
Price per item |
|
{{ item.image_url }} |
Item image URL |
The following variables will loop through order items:
{% for item in items %%}
<tr>
<td>{{ item.sku }}</td>
<td>{{ item.name }}</td>
<td>{{ item.quantity }}</td>
<td>{{ item.price }}</td>
</tr>
{% endfor %}
The following variables will show a gift message if one has been added to the order:
{% if gift_message != blank %}
<p><strong>Gift message:</strong> {{gift_message}}</p>
{% endif %}
The following variables will show custom carrier messages:
{% if gift message !=blank %}
<p>Your package ships via USPS. Delivery typically takes 2-3 business days.
The following variables will format the ship date as Month Day, Year.
{{ ship_date | date: "%B %d, %Y" }}
Tags are the logic layer of Liquid and will not appear in the printed output. Tags are instructions for Liquid and control what your template does. Use them to make decisions, repeat content, or store values.
Tags are wrapped in curly braces with percent signs, and most tags have an opening and a closing version. The content between the opening and closing tag is what gets acted on.
For example you can create a tag to only show a gift message if one has been added to the order.
{% if gift_message != blank %}
<{{ gift_message }}>
{% endif %}
The tables below include all available Tags that can be used when customizing your packing slips.
Control Flow Tags:
Use these to show or hide content based on conditions, for example, displaying a gift message only when one exists, or changing the copy depending on which carrier was used.
|
Tag |
Description |
Example |
|---|---|---|
|
if / elsif / else / endif |
Conditional logic |
{% if gift_message != blank %} |
|
unless / endunless |
Opposite of if |
{% unless carrier == "USPS" %} |
|
case / when / endcase |
Multi-condition switch |
{% case carrier %}{% when "UPS" %} |
Iteration Tags:
Use these to loop through a list of items. Everything inside the loop repeats once per item.
|
Tag |
Description |
Example |
|---|---|---|
|
for / endfor |
Loop over a collection |
{% for item in items %} |
|
break |
Exit a loop early |
{% break %} |
|
continue |
Skip to next iteration |
{% continue %} |
|
limit |
Limit loop iterations |
{% for item in items limit: 5 %} |
Variable Tags:
Use these to store and reuse values within your template. These tags are useful for building strings or repeated content.
|
Tag |
Description |
Example |
|---|---|---|
|
assign |
Set a variable |
{% assign label = "Priority" %} |
|
capture/endcapture |
Capture a block of text into a variable |
{% capture msg %}Hello{% endcapture %} |
Filters let you transform a value before it's displayed. Filters are great for keeping your output clean and consistent without needing to manually format data in ShipStation. They're added to a variable using a pipe character (|) and can be chained together to apply multiple transformations at once.
For example {{ item.name | upcase | truncate: 30 }} takes the item name, converts it to uppercase and, if applicable, shortens it to 30 characters. The original value in your order isn't changed, Filters only affect how the value is displayed on the packing slip.
The tables below include all available Filters that can be used when customizing your packing slips.
String Filters:
Use these to clean up, format, or transform text values before they're printed.
|
Filter |
Description |
Example |
|---|---|---|
|
upcase |
Converts to uppercase |
{{ carrier | upcase }} → USPS |
|
downcase |
Converts to lowercase |
{{ store.name | downcase }} |
|
capitalize |
Capitalizes first letter |
{{ item.name | capitalize }} |
|
strip |
Removes leading/trailing whitespace |
{{ gift_message | strip }} |
|
truncate |
Shortens to specified characters |
{{ item.name | truncate: 30 }} |
|
replace |
Replaces a substring |
{{ order_number | replace: "#", "" }} |
|
prepend |
Adds text to the front |
{{ order_number | prepend: "Order #" }} |
|
append |
Adds text to the end |
{{ store.name | append: " Team" }} |
|
remove |
Removes all occurrences of a substring |
{{ item.name | remove: "SAMPLE-" }} |
|
size |
Returns string length |
{{ item.name | size }} |
|
split |
Splits string into an array |
{{ "a,b,c" | split: "," }} |
Number Filters:
Use these to do numeric calculations like line item totals or price formatting.
|
Filter |
Description |
Example |
|---|---|---|
|
plus |
Addition |
{{ item.price | plus: 5 }} |
|
minus |
Subtraction |
{{ order_total | minus: 10 }} |
|
times |
Multiplication |
{{ item.price | times: item.quantity }} |
|
divided_by |
Division |
{{ order_total | divided_by: 2 }} |
|
modulo |
Remainder |
{{ item.quantity | modulo: 2 }} |
|
round |
Rounds to a specified decimal place |
{{ item.price | round: 2 }} |
|
floor |
Rounds down |
{{ item.price | floor }} |
|
ceil |
Rounds up |
{{ item.price | ceil }} |
|
abs |
Absolute value |
{{ discount | abs }} |
Data Filters:
Use these to format date values into a readable format.
Array Filters:
Use these when working with lists; array filters let you sort, count, extract specific fields, or deduplicate values.
|
Filter |
Description |
Example |
|---|---|---|
|
first |
Returns first item |
{{ items | first }} |
|
last |
Returns last item |
{{ items | last }} |
|
size |
Returns the number of items |
{{ items | size }} |
|
join |
Joins array into a string |
{{ tags | join: ", " }} |
|
sort |
Sorts an array |
{{ items | sort: "name" }} |
|
map |
Extracts a property from each item |
{{ items | map: "sku" }} |
|
uniq |
Removes duplicates |
{{ items | map: "sku" | uniq }} |
|
reverse |
Reverses an array |
{{ items | reverse }} |
Default Filter:
Use this if you need to have fallback information to replace an empty variable instead of leaving a blank space.
|
Filter |
Description |
Example |
|---|---|---|
|
default |
Falls back to a value if variable is blank |
{{ gift_message | default: "No message" }} |
Packing slip templates can generate QR codes directly from your order data - no external services or image files required. This is useful for scannable order numbers, tracking references, or links back to an order page.
Use the {% qr %} tag to render a QR code. Whatever you put between {% qr %} and {% endqr %} becomes the data encoded in the QR code.
Simple Example:
{% qr %}Hello World{% endqr %}
With a Variable (most common use case):
This renders a QR code containing the order number. When someone scans it with a phone camera, they'll see the order number text.
{% qr %}{{ order_number }}{% endqr %}
Custom Size:
By default QR codes render at 150×150 pixels. You can change this:
{% qr width: 200, height: 200 %}{{ order_number }}{% endqr %}
-
Liquid is only available in the Packing Slip HTML editor.
-
JavaScript execution tags are not supported.
-
Shopify-specific Liquid objects (like shop, customer, or checkout) are not available — only the ShipStation variables listed above.
-
To learn more about Liquid Logic see:
-
Liquid official documentation contains syntax reference for objects, tags, and filters.
-
Liquid basics: Introduction best to start here if you're new to Liquid.
-
Liquid on GitHub is an open source reference and changelog.
-