ShipMantaSupport Center
Advanced

Documents

Design picking lists, packing slips, invoices, manifests, item labels, and the Local Pickup Slip — Mustache tokens, messages, Rate Shopper shopped rates, and print filters.

Intro

Documents controls the layouts your team prints — picking lists to pull stock, packing slips for the box, invoices, manifests, item labels, and the pickup slip. Once configured, they print from the Print menus on Orders and Shipments.

Purpose

  • One consistent layout per document type for the whole store
  • Include exactly the fields your bench and customers need — including custom fields and destination weather

Document types

TypeMoment
Picking List / Order Pick ListPulling stock for one shipment or order
Batch Pick ListPulling stock for many shipments at once, grouped and sorted for the warehouse walk
Packing SlipIn the box; barcode source for Scan & Ship
InvoiceCustomer or B2B paperwork
Returns SlipIncluded for returns
Shipment ManifestCarrier handoff at end of day
Item LabelOne label per unit (per-quantity printing)
Local Pickup SlipCounter handover — see Local Pickup
Custom DocumentAnything else

Every store starts with sensible defaults for each type; edit them or create additional documents.

Configure a document

  1. Open Advanced → Documents and create a document or open an existing one.
  2. Choose the type, then the page: A4, Letter, Legal, A5, A3, or Custom (inches); Portrait / Landscape; margins.
  3. Edit the Header, Body, Footer, and CSS tabs. Use Insert variable to place data — see Template variables. Turn on Tailwind CSS to use utility classes instead of writing CSS.
  4. In Printing, set the defaults the print preview starts from — see the table below.
  5. Watch the live preview: it renders with sample data until you pick one or more real shipments (or orders) in the preview picker, which is the quickest way to check bins, metafields and custom fields on your own data. Save, then print a test from a shipment.

From the Documents list each row offers Duplicate (copy layout and printing defaults under a new name — the starting point for one template per product group), Activate / Deactivate (inactive documents disappear from Print menus but keep their layout) and Delete; a star marks the Default document of each type, set in the editor.

Printing defaults

SettingWhat it does
Group items byConsolidated lists only (Batch Pick List, Manifest): one row per SKU + bin, per SKU, or per SKU + warehouse location
Sort rows byDefault row order, e.g. Bin location so pickers walk the warehouse in order
Default locationOnly print item rows stocked at this Shopify location. Empty = all locations
Default conditionA Condition applied whenever this document prints — e.g. Fish products. Empty = none
Per quantityItem labels: one label per unit / pack instead of one page per shipment
ConsolidateOne combined document for the whole selection instead of one page per shipment
DefaultPreselected in the Print menu for its type

Location and condition are defaults, not locks: the print preview preselects them and the operator can change them for one print without touching the document.

Templates use Mustache syntax. The short example below prints weather only when a forecast exists; the full syntax table is in Template syntax.

{{# weather }}Destination: {{ low }}–{{ high }}{{ unit }} · {{ condition }}{{/ weather }}

Template syntax (Mustache)

Documents are HTML plus Mustache tags. Nothing outside {{ … }} is evaluated. The editor's Insert variable and Helpers insert the same tags.

SyntaxNameWhat it does
{{ name }}VariablePrints the value. Empty values print nothing (no error). HTML in the value is escaped.
{{{ name }}}UnescapedSame as {{ name }} but allows HTML through — only use for trusted markup.
{{# section }}…{{/ section }}Section (if / loop)If section is a list, repeats the block once per item (each item is the current context). If it is a truthy value (true, non-empty string, non-empty object), prints the block once. If missing / empty / false, prints nothing.
{{^ section }}…{{/ section }}Inverted sectionThe opposite of #: prints the block only when the value is missing, empty, or false — useful for fallbacks ({{^ sku }}-{{/ sku }}).
{{> partial }}PartialInserts a reusable snippet from the helper list (row_messages, head_messages, shopped_tag, shopped_service, bin_cell, …).
{{# barcode }}…{{/ barcode }}HelperRenders the inner value as a Code 128 barcode SVG (what Scan & Ship reads).
{{# qr }}…{{/ qr }}HelperRenders a QR code SVG.
{{# money }}…{{/ money }}HelperFormats a number as money (12.5 → 12.50).

Truthiness for sections. Use flags the renderer provides — has_discount, has_messages, has_shopped_rate, has_multiple_bins, shipment.local_pickup — rather than guessing. A missing Rate Shopper result makes has_shopped_rate false, so {{# shipment.has_shopped_rate }}…{{/ shipment.has_shopped_rate }} (and the shopped_* partials) stay blank.

Nested paths. Dot notation walks the context: {{ shipment.label }}, {{ shipping.postal_code }}, {{ metafields.binlocation }}, {{ custom_fields.item_bin_location }}. Inside a loop the current row is the context ({{ sku }} inside {{# items }}), and you can still reach parents ({{ shipment.label }}).

Common patterns

{{# items }}
  {{ name }} · {{ sku }}
  {{# has_discount }}was ${{ price }}{{/ has_discount }}
{{/ items }}

{{# shipment.has_shopped_rate }}
  Shopped {{ shipment.shopped_label }} ${{ shipment.shopped_amount }}
{{/ shipment.has_shopped_rate }}
{{^ shipment.has_shopped_rate }}
  <span class="muted">Not shopped</span>
{{/ shipment.has_shopped_rate }}

{{> shopped_tag }}
{{> shopped_service }}

Mustache has no <, >, =, or contains operators inside the template. Comparisons live in Conditions (document Default condition, print Filter rows by condition, and document messages). In the template you only show or hide blocks with # / ^.

Bin location on pick lists

{{ bin_location }} on an item row resolves in this order:

  1. A product or variant metafield synced for bin location (e.g. custom.bin_location)
  2. A line-item custom field whose name contains bin — e.g. Item Bin Location captured from variant.metafield:custom.bin_location (see Custom Fields)
  3. Otherwise -

To print a specific custom field regardless of its name, use its slug: {{ custom_fields.item_bin_location }} (the field name lower-cased with underscores). Custom fields and metafields can also be sort columns (custom_fields.<slug>, metafields.<key>). The Shopify location id is never printed as a bin.

Bins per location. When Advanced → Locations maps a bin metafield to a location, {{ bin_location }} follows the Location chosen in the print dialog: a mapped location prints its own metafield (falling back to the default above), an unmapped one prints the default. With All locations, has_multiple_bins is true and the bins loop lists one entry per mapped location that has a value — location, location_short, key, value. The seeded pick lists already print {{# has_multiple_bins }}{{# bins }}{{ location_short }} {{ value }}{{/ bins }}{{/ has_multiple_bins }} and fall back to {{ bin_location }}; the Bin per location helper snippet inserts the same block. The AI assistant can make that edit too: it reads the template and saves the new HTML, and shows you the before and after before anything is saved.

Template variables

Insert variable lists everything available for the document's scope and drops it into the pane you are editing. The main groups:

GroupExamples
Shipment / Ordershipment.label, shipment.full_label, shipment.delivery_date, shipment.shipby_date, shipment.staff_picked_by, shipment.notes_text, order.label, order.order_date, order.payment_status
Shopped rate (Rate Shopper)See Shopped carrier & service
Customer, Shipping address, Billing address (order scope)customer.full_name, shipping.address_1, shipping.postal_code, …
Items (loop){{# items }} … {{/ items }} with line_number, name, sku, barcode, quantity, price, discounted_price, line_discount, line_total, has_discount, vendor, type, image, location (fulfillment location name), location_short (the text before |, e.g. Online), locations_text, bin_location, has_multiple_bins + bins loop (per-location bins, see Locations), order_label (which order the line came from on merged shipments), metafields.<key>, custom_fields.<slug>
Item label (per-quantity documents)item.name, item.sku, item.quantity, item.sequence ("2 of 3"), item.label_index / item.label_count, plus the same metafield and custom-field tokens
Supplies — consolidated (loop)Batch Pick List / Manifest only: {{# supplies }} rows grouped per Group items by, with required (total units) and a nested {{# orders }} loop of label / quantity
Messages (loop)has_messages and {{# messages }}{{ text }}{{/ messages }} with text, style, name — at the top level (shipment / order messages), inside items and supplies (per-line messages) and as item.messages on item labels; see Messages on documents
Merged orders{{# all_orders }}{{ label }}{{/ all_orders }} lists every order on the shipment (or in the whole batch); merged_shipments, has_merges, and all_order_labels cover the merge lineage
Product metafieldAny synced custom.* key — type it or pick from the chips: {{ metafields.binlocation }}
Weather / Named addressesDestination forecast and addresses.<key> blocks from the Weather app
Tags, Notes, Shipping methods, Units by product typeLoops over the shipment's tags, notes, shipping lines, and per-type unit counts
Store, Totals, Documentstore.name, store.logo, totals.quantity, generated_at, count (shipments in the batch)

Helpers wrap a value: {{# barcode }}{{ shipment.label }}{{/ barcode }} renders a Code 128 barcode (what Scan & Ship reads), {{# qr }}…{{/ qr }} a QR code, {{# money }}{{ price }}{{/ money }} a formatted amount. See Template syntax for #, ^, and >.

Shopped carrier & service (Rate Shopper)

When Rate Shopper has picked a winner for the shipment, the same values as the Shopped Carrier and Shopped Service columns on the Shipments table are available on the document. Nothing is invented at print time — if the column is a dash on the table, the tokens stay empty and the partials print nothing.

TokenMeaning
shipment.has_shopped_ratetrue when a winner exists (use with {{# … }})
shipment.shopped_carrierDisplay name — FedEx, UPS, USPS, DHL
shipment.shopped_serviceHuman service name — FedEx Ground, UPS · 2nd Day Air
shipment.shopped_labelBest single string for a pill or line (avoids FedEx · FedEx Ground)
shipment.shopped_amountWinner amount as 12.50
shipment.shopped_currencyCurrency code when present
PartialPrintsSeeded on
{{> shopped_tag }}Green supporting pill with shopped_labelOrder Pick List, next to shipment tags
{{> shopped_service }}A line: Shopped label $amountOrder Pick List and Order Slip / packing-style headers, under Service

Needs the Rate Shopper app on the plan. Custom templates: insert the helpers from the editor list, or ask the AI assistant to add them (it will preview the HTML change first).

Prices and discounts. price is the raw unit price, before any line discount. When a line is discounted, discounted_price is the unit price the customer actually pays, line_discount the amount taken off, and line_total the discounted quantity × price — the same figures the shipment page shows. has_discount lets a template strike through the original only when there is one:

{{# money }}{{ discounted_price }}{{/ money }}
{{# has_discount }}<s>{{# money }}{{ price }}{{/ money }}</s>{{/ has_discount }}

A 100% line discount prints 0.00, not the full price. Product thumbnails are cached and embedded when a PDF is generated, so a batch of a few hundred lines does not wait on the Shopify CDN.

Messages on documents

Advanced → Documents → Messages (Pro and Enterprise) prints a short note on a document when a Condition matches — "Add a heat pack" under every frozen line, "Fragile — double box" at the top of orders tagged fragile, "Pick from the cold room" next to items stocked at a given location. Nothing is stored on the order or shipment: messages are resolved every time a document renders, so changing a message or its condition changes the next print, including reprints of old shipments.

A message has:

FieldMeaning
ConditionAny condition, active or not. Leave empty to always print.
WherePer matching line (the condition's Product item rules decide which lines; shipment / order / customer rules gate the whole document) or Once per shipment / order (near the header when the shipment matches). Where the note sits on the page is decided by the template partial — see below.
MessageUp to 1000 characters. Tokens work the same way as in templates: {{ sku }}, {{ location }} and the other item tokens for per-line messages, {{ shipment.label }}, {{ order.label }}, {{ customer.full_name }} for both.
StylePlain (default — just the text, same line as surrounding content) or a coloured pill: Info (blue), Warning (amber), Danger (red), Success (green). Use a pill when the note must stand out; keep Plain for quiet bench notes like "Back in bin location."
DocumentsLimit the message to some documents; empty means every document.

New messages start as drafts. Test on a shipment (per message, or for all of them from the toolbar) runs the real engine on a real shipment and shows which messages print at the top and on which lines — drafts included — then switch the message on. Messages print in list order; use Move up / Move down to change it.

Where they appear on the page. Templates print messages wherever they contain one of the partials. Partials are inline, so Plain text sits on the same line as the surrounding words (e.g. Orders: #158464 (qty: 4) Back in Bin Location.).

PartialPrintsAlready in
{{> row_messages }}Per-line messages for that item / supplies rowBatch Pick List / Pick Slip: on the Orders: line next to the order numbers. Other seeded templates (picking list, packing slip, invoice, local pickup, manifest, order pick list): next to the item name
{{> head_messages }}Shipment / order messages, once, near the headerThe seeded templates, next to the notes / ship-to block
{{> item_messages }}Per-line messages on an item label (item.messages)Both seeded item labels
{{# messages }}…{{/ messages }}Your own markup with text, style and name—

Existing stores get the partials added (and Pick Slip / Batch Pick List relocated onto the Orders line) on upgrade when the row markup is the one that shipped; a heavily customised template keeps rendering unchanged until you add a partial yourself — pick Messages for an item / Orders line / Messages for the shipment / order from the editor's helper list, or ask the AI assistant to patch the template. Consolidated supplies rows on the Batch Pick List and Manifest show the union of the messages of the lines they combine.

Messages do not slow printing down: the list is loaded once per print, the conditions are evaluated in memory per shipment and per row, and a store with no messages pays one small query.

Conditions on messages use the same operators as everywhere else (=, !=, >, >=, <, <=, contains, …) — see Conditions → Operators. The template itself never evaluates those operators; the condition engine does, then the matching message text is printed.

Printing

Open Print on a shipment or order (or on a selection in a list) and pick a document. The preview opens with the document on the left and a panel on the right:

Page order for a selection. When you print several shipments at once (packing slips, order pick lists, Pack + Order, and similar one-page-per-shipment documents), the pages come out in the same order as the list you are looking at — whatever sort and filters you applied on Shipments. Sort the table the way you want to walk the warehouse, select the rows, then print.

ControlEffect
TemplateSwitch to another active document without closing the preview
Sort rows byRe-order item rows for this print
LocationOnly rows stocked at that location; shipments with nothing left are skipped. All locations comes first, then your own locations (busiest first), then partner, drop-ship and holding locations
Filter rows by conditionApply a Condition — see below
PrintOpens your browser's print dialog for the rendered pages (turn off "Headers and footers" there)
Download PDFGenerates a PDF with the same options
Open in new tabThe rendered pages in a browser tab — handy for a second screen or a printer kiosk

The preview is the real rendered document, so Print is immediate; only Download PDF waits for PDF generation. Changes in the panel apply to this print only. The document's saved defaults (sort, location, condition) are preselected each time you open it; "Save a default on the document" means editing it under Advanced → Documents.

Filter rows by condition

Pick any active Condition. Two kinds of rule behave differently:

  • Item rules (Product item entity — type, SKU, vendor, tags, collections, location, metafields…) hide the item rows that do not match. A shipment left with no rows is skipped.
  • Shipment-level rules (Order, Shipment, Customer, Shipping address, and the any item / no item gates) cannot be answered per row, so the whole condition is evaluated against each selected shipment and non-matching shipments are left out entirely — with all their rows.

A condition can mix both: order label starts with W and item type is Frozen prints only the frozen lines of wholesale orders. If nothing matches you get a single "No items match the selected filters" page instead of an unfiltered print.

Filters change what is printed only — hidden items still ship.

The "Printing" condition group

The dropdown lists every active Condition. To keep it short, create a rule group named Printing (any capitalisation) under Advanced → Conditions and move your print-only conditions into it: as soon as that group has one active condition, the print preview and the document editor list only that group. Stores without a Printing group keep seeing all conditions.

One template per product group

When a pick slip should look different for, say, fish and supplies, make two documents rather than one clever template:

  1. Duplicate the pick slip: Pick Slip – Fish and Pick Slip – Supplies.
  2. Give each its own layout, and set Default condition to Fish products / Supplies (and a Default location if the stock lives in one place).
  3. Both appear in Print and in the preview's Template switcher; choosing one gives the right layout with the right rows. The operator can still override the condition for a one-off print.

One row per fulfillment location

On a picking list, order pick list, batch pick list, Pick + Pack, and item labels, a line that Shopify has open at two or more fulfillment locations prints once per location, using that location's own quantity. A quantity of 3 with 1 at Online | Your Store and 2 at Retail | Your Store is two rows: Online required 1, Retail required 2. The pick-list column keeps the full location name. A line at only one location stays one row with the shipment quantity.

Packing slips, invoices, and the local pickup slip stay one line. Those go to the customer.

Item labels print the short name — the text before the | — under the shipment number ({{ item.location_short }}), including when the line is only at one location. In Split labels, two locations of the same product stay separate rows.

Item labels: split before printing

For Item Label (per-quantity) documents, Print… and Download PDF first open Split labels:

  • The list shows only the lines with quantity above 1 that will print under the current Location / Filter rows by condition — quantity-1 lines have nothing to split, print one label each, and are counted in the total. When every line is quantity 1 the popup is skipped and the print goes straight through.
  • Choose Print single label per line item or Break out every line item by quantity, or tick individual lines and set an optional pack per bag (20 snails, 5 per bag → 4 labels). The button shows the resulting label count.
  • Confirm and the labels print (or download). After that Print acts directly; Split labels… reopens the popup to change the plan, Reset goes back to one label per line.

Carrier labels are not documents: their format (PDF / ZPL / EPL) and Zebra Browser Print setup live under Printing.

Print and Download PDF are recorded per shipment (previews and Open in new tab are not). Each print adds a Document printed entry to the shipment's Activities and immediately re-runs the shipment automation rules on the affected Awaiting shipments, so print-driven rules fire without waiting for the next sync. Order-scoped documents count for every Awaiting shipment holding that order's items.

Two shipment fields in Conditions read this history:

FieldMeaningTypical rule
Printed documentNames of documents printed or downloaded for the shipmentPrinted document is empty → tag Not printed; Printed document contains Packing Slip → tag Slip printed
Printed document outdated by item changesPrinted documents whose last print is older than the last line-item change (item added or cancelled, quantity changed, lines split out or merged in)… contains Packing Slip → add tag Reprint; the negation → remove Reprint. Reprinting re-runs the rules and clears the tag

Address, customer, and shipping-method edits are not line-item changes and do not make a print outdated. A document that was never printed is never "outdated".

Who can use it

Documents (templates, print, PDF) are on every plan. Document messages are Pro and Enterprise — the Messages button and Advanced → Documents → Messages stay hidden on Basic. Shopped rate tokens need the Rate Shopper app (Pro+). Permissions View documents / Manage documents.

AI assistants (MCP) — with the Operations module:

ToolRole
operations_list_documents / operations_get_documentList templates; read full HTML (check for {{> row_messages }}, {{> shopped_tag }}, …)
operations_update_documentEdit any editor field; live changes need confirmation
operations_list_document_messages / operations_test_document_messagesList messages; dry-run on a real shipment (drafts included)
operations_create_document_messageCreate as a draft (style defaults to Plain / neutral)
operations_update_document_message / operations_delete_document_messageEdit, activate, or delete — activating or editing a live message needs confirmation
operations_list_print_historyWhat was printed for a shipment
orders_explain_rate_shopWhy Shopped Carrier / Service is filled or blank (feeds the same data documents print)

Read storesboost://operations/semantics for the full Operations vocabulary.

Troubleshooting

SymptomCheck
A condition in the preview "does nothing"It has only shipment-level rules and every selected shipment matches — that is a pass, not a filter. Add a Product item rule to hide rows
Every shipment disappears when I pick a LocationNo line item is assigned to that location. Item locations are the Shopify fulfillment location assigned to each line at import (fulfillment orders), so an order routed to another location has no rows there
Bin location prints a long numberFixed in current versions — the Shopify location id is no longer used as a bin. Make sure a bin metafield or bin custom field exists
The bin is wrong for the warehouse I print forMap each warehouse to its bin metafield under Locations and pick that Location in the print dialog
The Split labels list shows fewer lines than the shipment hasThe current Location / condition filter hides them; clear the filters in the preview panel
A pick list puts the whole quantity on the first locationThat line is open at more than one fulfillment location. Pick lists and item labels print one row per location, each with that location's quantity. Packing slips, invoices, and the local pickup slip stay one line
Condition dropdown is missing a conditionA Printing group exists and the condition is not in it; move it there or pick it as the document's default (defaults are always listed)
A message tests fine but does not printThe message is still a draft, is limited to other documents, or the template has no {{> row_messages }} / {{> head_messages }} partial — add it from the editor's helper list. A per-line message whose condition has no Product item rule prints under every line of a matching shipment
Shopped tag / line is blankRate Shopper has no winner for that shipment (Shopped columns are dashes on Shipments), or the template has no {{> shopped_tag }} / {{> shopped_service }} — add from Helpers. Confirm with orders_explain_rate_shop
{{# weather }} block never appearsDestination weather is off or not fetched — see Weather
Literal {{ sku }} prints on the pageThe tag was put in an HTML attribute that Vue or the editor stripped, or a brace was missing — use Insert variable