Overview
When you build a custom HTML Purchase Order (PO) print template in Luminous, each row in the {{#orderLines}} loop carries the SKU custom fields for that line's product. These are the same custom fields you've configured on your SKUs (products). They are grouped under a nested object called skuCustomFields, which supports several access patterns.
Step 1 — Understand where to place the placeholder
Your HTML template has an Item Row section (the itemRowHtml block). That is the only section that runs once per order line, so product custom field placeholders must go there, wrapped in the {{#orderLines}} loop:
{{#orderLines}}
... {{skuCustomFields.yourFieldKey}} ...
{{/orderLines}}
Step 2 — Know how Luminous generates the placeholder key
Luminous automatically converts each custom field's label (the name you gave it when creating the custom field on the SKU) into a camelCase key:
| Custom field label | Placeholder key |
|---|---|
| Color | color |
| Fabric Type | fabricType |
| HTS Code | htsCode |
| Country of Origin | countryOfOrigin |
The rule: spaces and special characters become underscores, the result is lowercased, then converted to camelCase.
Step 3 — Choose an access pattern
Direct access (most common)
Output the value of a single field by name:
{{skuCustomFields.fabricType}}
Formatted string (all fields at once)
Output all SKU custom fields as a comma-separated Label: Value list:
{{skuCustomFields}}
Example output: Fabric Type: Cotton, Country of Origin: USA
Loop (full control over markup)
Iterate over every SKU custom field on the line to render each one yourself:
{{#orderLines}}
{{#skuCustomFields}}
<span>{{label}}: {{value}}</span>
{{/skuCustomFields}}
{{/orderLines}}
Inside the loop you have access to:
{{key}}— the generated placeholder key (camelCase){{label}}— the human-readable field name{{value}}— the field value
Conditional display (only show if the field exists)
Wrap content so it only renders when the SKU has at least one custom field value:
{{#skuCustomFields._hasAny}}
Custom fields: {{skuCustomFields}}
{{/skuCustomFields._hasAny}}
Step 4 — Discover your exact field keys
You have two ways to look up the camelCase key for any specific custom field:
Option A — Placeholder reference API
Call the PO HTML placeholders endpoint (while authenticated as an admin). Look for the SKU Custom Fields section — it lists every custom field on your account along with the exact placeholder key to use:
GET /admin/manage/export-templates/purchase-order-html-placeholders
Option B — In-template debug helper
Temporarily add the following inside your {{#orderLines}} row while testing. It renders an HTML table showing every available key and its current value for each line:
{{{skuCustomFields._info}}}
Note: Use triple braces
{{{ }}}for_infoso that the HTML table it returns is not escaped.
Remove the debug placeholder before saving your final template.
Quick reference example
A minimal itemRowHtml that prints the SKU, description, quantity, and a product custom field called HTS Code:
{{#orderLines}}
<tr>
<td>{{sku}}</td>
<td>{{description}}</td>
<td>{{quantity.formatted}}</td>
<td>{{skuCustomFields.htsCode}}</td>
</tr>
{{/orderLines}}
Notes
- PO lines use SKU custom fields — PO line items do not have their own independent custom fields. The values come from the product (SKU) attached to each line.
- If a SKU does not have a value for a given custom field, the placeholder renders as empty (no error).
- The
itemCustomFieldskey inside{{#orderLines}}provides the same data asskuCustomFieldsand can be used interchangeably. - For order-level (header) PO custom fields, use
{{orderCustomFields.yourFieldKey}}outside the loop instead.