ZPL Template Generator: Start With the Workflow, Not a Blank Label
A blank label is a surprisingly bad starting point. Real labels come from a workflow: a packer scans an order, a technician sticks an asset tag under a desk, a receiving clerk prints pallet IDs, or a production line applies a lot label before the carton closes.
The ZPL Template Generator is most useful when you bring that workflow into the template: label size, printer DPI, barcode data, readable fallback text, and the exact fields an operator needs when the scanner fails.
Demo 1: a clean 4x6 shipping label
Start with size and DPI. A 4x6 label at 203 DPI is roughly 812 x 1218 dots. Put the tracking barcode in a predictable scan area, then reserve text above and below it.
^XA
^CI28
^PW812
^LL1218
^FO50,45^A0N,42,42^FDShip To:^FS
^FO50,100^A0N,32,32^FDJane Rivera^FS
^FO50,145^A0N,28,28^FD42 Dock Street, Austin TX^FS
^FO50,240^GB710,2,2^FS
^FO70,300^BY3
^BCN,150,Y,N,N
^FD1Z999AA10123456784^FS
^FO70,500^A0N,30,30^FD1Z999AA10123456784^FS
^XZ
Preview this in the ZPL Viewer. If the barcode nearly touches the right edge, do not shrink it blindly. First check whether your tracking number can be shorter, whether the module width is too large, or whether the barcode should rotate.
Demo 2: product label with variables
For ERP and ecommerce systems, the template should make variable fields obvious. That makes QA easier and reduces accidental edits to static text.
^XA
^CI28
^PW609
^LL406
^FO35,35^A0N,36,36^FD{{product_name}}^FS
^FO35,85^A0N,26,26^FDSKU: {{sku}}^FS
^FO35,135^BY2
^BCN,100,Y,N,N
^FD{{sku}}^FS
^FO35,280^A0N,24,24^FDLot: {{lot}} Exp: {{expiry}}^FS
^XZ
After generating a draft, use ZPL Variable Mapper to list placeholders and confirm nothing important is hard-coded.
Demo 3: asset tag with QR fallback
Asset labels often live for years. Give them a QR code for systems, and plain text for humans.
^XA
^PW406
^LL305
^FO28,28^A0N,30,30^FDAsset LAP-20491^FS
^FO28,78^BQN,2,5
^FDLA,https://example.com/assets/LAP-20491^FS
^FO175,105^A0N,22,22^FDService history^FS
^FO175,140^A0N,22,22^FDScan QR code^FS
^XZ
What to adjust after generation
- Use ZPL DPI Converter before moving a 203 DPI template to 300 DPI.
- Use ZPL Field Inspector to review coordinates, text, and barcode commands.
- Use Barcode Scan Checker before approving production labels.
- Keep large logos away from barcode quiet zones.
- Keep at least one human-readable field for every critical barcode or QR value.
A small QA script for generated labels
If you generate labels from an order system, add a lightweight check before the ZPL is sent to the print queue. It does not need to understand every command. It only needs to catch missing fields and values that are obviously too long for the template.
const required = ["{{order_no}}", "{{tracking_number}}", "{{customer_name}}"];
for (const token of required) {
if (!template.includes(token)) throw new Error(`Missing ${token}`);
}
if (order.customer_name.length > 36) {
console.warn("Customer name may overflow the shipping label");
}
This kind of small guard catches many template mistakes before they become printer tickets. The generator gives you a good starting layout; your application still owns the data rules.
Promote templates deliberately
When a generated label graduates from draft to production, treat it like application code. Give it a version, sample data, a preview proof, and an owner. Keep the variable contract near the ZPL so a future developer knows whether {{sku}} can contain spaces, whether {{expiry}} is ISO format, and whether {{tracking_number}} is always valid Code 128 data.
template contract:
name: product-sku-2x1-v4
dpi: 203
variables:
product_name: max 32 visible characters
sku: Code 128-safe ASCII
lot: optional, max 18
approval:
preview: passed
barcode scan: passed
owner: warehouse systems
Before promotion, open the label in the ZPL Field Inspector, run Readiness Checker, and keep an Approval Report with the release note.
A generator should save you from repetitive setup, not from thinking. The best templates still come from watching how the label is used.
