Admin Print Action Extensions
Admin print actions add a “Print” button to an admin resource page that produces a print-ready document for that resource — packing slips, branded invoices, gift receipts, return forms, pick lists, anything that ends in awindow.print() call.
Unlike Admin Actions (which open an interactive
modal), print actions exist for one job: render a printable view and hand
it to the browser’s native print dialog. The host page automatically
opens a new window, drops the rendered HTML into it, and triggers
window.print() as soon as the page paints.
The current build renders printable HTML and uses the browser’s native
print dialog. Headless-Chrome PDF generation, page-size hints, and direct
receipt-printer support are tracked as future work — see
Roadmap.
How it works
The host (the admin) opens the response in a new window:- Template mode — the response includes
htmlalready wrapped in a print-ready envelope (with<script>window.print()</script>baked in). The new window writes the HTML, the script fires onload, and the print dialog opens automatically. - Iframe mode — the host points the new window at your
iframeUrl. Your app is responsible for fetching whatever it needs, rendering the printable view, and callingwindow.print()itself.
Two rendering modes
You choose one of these per print action. The choice is dictated by which field you set on the manifest:template (string of Aqua/Liquid)
or appUrl (HTTPS URL).
Template mode
Ship an Aqua/Liquid template string. The platform renders it
server-side with the resource id in context and returns HTML wrapped
in a print envelope. Zero app-server work at print time.
Iframe mode
Ship a URL. The platform returns a signed URL the host opens in a new
window. Your app generates the printable view dynamically, fetching
whatever live data it needs.
template and appUrl. The
server checks appUrl first; if both are set it’s used and template is
ignored. Pick one.
Available targets
Additional
admin.{resource}-details.print.render targets for product,
draft order, gift card, customer, and shipment pages are planned as the
respective admin detail pages get wired in. Track this in the
Roadmap.Extension manifest
Each print action is one entry inextensions.printActions on your
app.json. After install, each entry is persisted as a single schema
file at:
Template-mode manifest
Iframe-mode manifest
Fields
The schema persisted on disk is the manifest entry verbatim (with
name
and title merged for back-compat). Schema mode is detected at print
time by checking appUrl first, then falling back to template.
Rendering endpoint
When the merchant clicks the print menu item, the admin host sends a POST to the platform to resolve the action:domainSlug, appHandle, handle. resourceId and
resourceType are surfaced to your template and as iframe query params.
An Authorization: Bearer header must be present — a request without
one returns 401 {"error":"Missing bearer token"}. The admin host adds
the merchant’s token automatically when it calls this endpoint; you only
need to send it yourself if you’re calling the endpoint directly (e.g.
while testing). The endpoint is CORS-open (Access-Control-Allow-Origin: *) so the admin can call it cross-origin.
Template-mode response
<script>window.print()</script> fires automatically once the
page paints.
Iframe-mode response
iframeUrl in a new window. The query params are appended
automatically — see Iframe-mode details.
Error responses
Template-mode details
In template mode your Aqua/Liquid template is rendered server-side using the same engine that powers theme rendering. You get the full filter library (money, date, default, escape, etc.) and the full
render / include / for syntax.
The context exposed to the template is intentionally minimal in the
current build:
resourceType is "order" you can write {{ order.id }}; when
it’s "customer" you’d write {{ customer.id }}. The mirror always
maps to the literal resourceType string, so an unknown resource type
will surface as {{ <resourceType>.id }}.
The rendered HTML is wrapped in a minimal envelope:
@media print rule zeroes padding so your content prints
edge-to-edge. Override it in your own <style> block if you need
margins.
Example: packing slip template
Example: minimal invoice template
Iframe-mode details
In iframe mode yourappUrl is opened in a new window with these query
parameters appended:
If your
appUrl already contains a query string, the params are merged.
If appUrl is unparseable as a URL (relative path, missing scheme), it
is returned as-is and the host opens it verbatim.
Your printable page should:
- Read the params. They tell you which resource to render.
- Authenticate. If you need to call your own backend, obtain a session token through App Bridge and include it in your fetch.
- Render the page. Same DOM you’d use for any printable web view.
- Print. Call
window.print()once the DOM is fully painted — typically inside aloadhandler or a shortsetTimeoutso images have time to lay out.
Why use iframe mode
- You need the full resource (line items, addresses, customer fields) that template-mode context doesn’t expose yet.
- The printable view depends on data only your service has (subscription cadence, custom inventory state, multi-warehouse pick paths).
- You want to ship marketing/branded HTML that you control end-to-end without redeploying the merchant’s app.
Why use template mode
- Zero app-server work at print time. The platform is the only thing online.
- You only need the resource id stamped on a layout (gift receipt with no prices, simple thank-you slip).
- You want offline-friendly behaviour — no need for the merchant to have working internet to your app, only to LaunchMyStore.
Installing print actions
Print actions install through the same/api/apps/install-extensions
endpoint as other extension types. Add a printActions array under
extensions:
admin_print_action type to the host, which renders them as menu items
inside the merchant’s “Print” dropdown in the admin.
Subsequent installs overwrite existing schema files — there is no
“add to existing” semantics. Always send your full set of print actions
on each install.
Multiple print actions per app
One app can register many print actions for the same target — they all appear in the merchant’s “Print” menu and are sorted byhandle. This
is the typical pattern for warehouse / fulfilment apps that ship a
suite (packing slip + pick list + return form + gift receipt):
Use cases
- Packing slips — pulled at the warehouse, listing what to grab before sealing the box.
- Branded invoices — custom layouts with the merchant’s logo, terms, bank details, tax IDs.
- Gift receipts — recipient-friendly receipts that hide prices.
- Return labels / RMA forms — pre-filled return paperwork the customer service rep can hand to the customer.
- Pick lists — multi-order picking sheets used by fulfilment teams.
- Compliance documents — country-specific export forms, dangerous goods declarations, customs invoices.
Print action vs admin action
Roadmap & hardware integration
The current build is intentionally minimal — printable HTML + browser print dialog. Several extensions are tracked for future releases:- Headless-Chrome PDF rendering. Optional server-side flag on the
manifest (
renderAs: 'pdf') that returns a PDF buffer instead of HTML, so the merchant can save / email the result without re-rendering client-side. - Resource hydration in template mode. Expose the full order / product / customer object on the Aqua context so templates can render line items, addresses, and totals without iframe mode.
- More targets. Print actions on the product detail page (barcode labels), draft order page (proforma invoice), gift card page (printed gift card), and shipment page (carrier label).
- Receipt-printer / thermal-printer integration. Today the platform uses the browser print dialog only — any printer the OS exposes works (laser, inkjet, label printer, thermal receipt printer). Direct ESC/POS or ZPL output to a USB/network receipt printer (without the browser dialog round-trip) is not wired and will require a native bridge or a WebUSB-based POS-side helper. Track this in the roadmap; for now, point your thermal printer at the OS print queue and pick it in the browser dialog.
- Print presets. Save a merchant’s preferred paper size, orientation, and margins per action so the dialog opens with the right defaults.
- Bulk print. Select N orders in the order list and run a single print action across all of them (useful for end-of-day fulfilment).
See also
- Admin Actions — modal-triggered UI variant.
- Admin Blocks — inline iframe panels.
- Aqua Filters — for use inside
templatestrings. - App Bridge: Session tokens — for authenticating iframe-mode requests to your backend.