Executive summary
- What: POS UI Extensions 2026-07 adds the Printing API, letting extensions discover hardware printers and print straight to a connected receipt printer with no system dialog.
- Why: The previous API could only open the system print dialog, which cannot target a dedicated receipt printer. That made unattended receipt and label printing impossible.
- Who: App developers and technical leads building custom POS workflows for retail, plus the store operations teams who depend on them.
What changed
The new namespace is shopify.printing. Calling getPrinters() returns the hardware printers available to the device, each with an id, a name, and a connected status. Calling print(src, options) sends a document. If you omit options.printer, the system print dialog opens as before. If you pass a printer returned by getPrinters(), the document goes directly to that printer with no dialog at all.
Two constraints shape the implementation. The src must be either a relative path appended to your app application_url or a full URL on the same origin, and the document is fetched using the extension session token. Receipt printers render HTML and images directly, but PDFs are dialog only: passing a printer when src points to a PDF throws an error, so for PDFs you always omit options.printer.
The older shopify.print is deprecated but still functional, and earlier API versions are unchanged. There is no forced migration. Plan the move when you adopt 2026-07.
Why it matters
For enterprise retail, the removed dialog is the whole point. Any workflow that printed a receipt, a gift note, a pick ticket, or a shipping label previously interrupted a staff member with a modal they had to tap through. At a busy counter that is a few seconds per transaction and a reliable source of mistakes when someone selects the wrong destination under pressure.
There is a version dependency worth planning around. Hardware printer discovery requires Shopify POS 11.11.0 or later. On earlier versions getPrinters() returns an empty array even when a receipt printer is paired, which means a naive implementation silently prints nothing. Always handle the empty array by falling back to the system dialog. That fallback also covers the perfectly normal case of a merchant with no receipt printer attached, so treat it as the default branch rather than an error path.
Custom POS extensions are increasingly where enterprise retail differentiation lives, a pattern we explored in how custom Shopify apps elevate your store.
Role-specific impact
- Marketers: Printed touchpoints become viable again. Personalised gift receipts, loyalty vouchers, and promotional inserts can print automatically at checkout without adding steps for staff.
- Developers: Migrate from shopify.print to shopify.printing when you adopt 2026-07, keep documents on the same origin as your application_url, and route PDF output through the dialog rather than a direct printer target.
- Store admins: Confirm your POS fleet is on 11.11.0 or later before expecting direct printing, and verify receipt printers are paired at each location.
Use-case example
Real-world scenario
A specialty grocer runs a custom POS extension that prints allergen information alongside the receipt for prepared foods. Under the dialog based flow, staff tapped through a print modal on roughly 400 transactions a day per store, adding about five seconds each, close to 35 minutes of counter time daily. Moving to a direct printer target removes the interaction entirely, and because the extension falls back to the dialog when getPrinters() returns empty, the three locations still on an older POS build keep working through the transition rather than failing silently.
Implementation checklist
- Inventory every extension currently calling shopify.print and note which outputs are HTML or images versus PDF.
- Adopt POS UI Extensions 2026-07 and replace shopify.print calls with shopify.printing.
- Call getPrinters() and select a printer where connected is true, falling back to the dialog whenever the array is empty.
- Route all PDF output through the system dialog by omitting options.printer, since passing one throws.
- Confirm every src resolves to a relative path on your application_url or a same origin URL.
- Test on a development store running POS 11.11.0 or later with a paired receipt printer, and confirm the job prints with no dialog.
FAQ
Q: Do we have to migrate off shopify.print immediately?
A: No. It is deprecated rather than removed, and earlier API versions are unaffected. Schedule the migration as part of your move to 2026-07 instead of treating it as an emergency.
Q: Why does getPrinters() return nothing when a printer is clearly paired?
A: Hardware discovery requires Shopify POS 11.11.0 or later. On earlier builds the array is empty regardless of pairing, which is why the fallback to the system dialog is mandatory rather than optional.
Resources
POS UI Extensions Printing API reference
Need guidance? Talk to Makro.