POS UI Extensions 2026-07 / New API

The Printing API arrives
POS extensions can now print directly to receipt printers

The existing shopify.print could only open the system print dialog, and had no way to target a dedicated receipt printer. The new shopify.printing enumerates the printers connected to the device and sends print jobs directly, with no dialog.

What's on this page
  1. In 30 seconds: what changed
  2. How it works: the path a print job takes
  3. Two APIs: getPrinters() and print()
  4. Compared with the old shopify.print
  5. Rules for src and document formats
  6. Implementation pattern (fallback required)
  7. 5 points developers should know
  8. 3 use cases you can put to work
  9. A one-line summary for your pitch

1In 30 seconds: what changed

POS UI Extensions 2026-07 introduces Printing API(shopify.printing).
From an extension you can enumerate the hardware printers connected to the device , andwithout opening a print dialog, send documents straight to a receipt printer.

Before: shopify.print

could only "open the system print dialog." The dialog can't target a dedicated receipt printer, so staff had to pick one by hand every time — or couldn't print at all.

Now: shopify.printing

getPrinters() retrieves the connected printers, andprint(src, {printer}) prints directly. No dialog appears.printer can be omitted to keep using the dialog as before.

The old shopify.print is now deprecated, butno immediate action is required. Plan the migration whenever you adopt 2026-07. Earlier POS UI Extensions API versions are unchanged.

2How it works: the path a print job takes

POS UI Extension getPrinters() print(src, opts) Extension code ① Enumerate Shopify POS device id / name / connected List of paired printers Requires POS 11.11.0 or later Hardware discovery ② Fetch Branch Was printer passed? Is src a PDF? Decided by your implementation Straight to the receipt printer No dialog / HTML & images System print dialog When printer is omitted / PDFs go here
The document is fetched using the extension's session token. In other words, your app's print endpoint just needs to authenticate with that token and return the content.

3Two APIs: getPrinters() and print()

shopify.printing.getPrinters()

Returns the list of hardware printers available on that device . Each printer has id / name / connected(connection status).

always an empty array below POS 11.11.0. It stays empty even when a receipt printer is already paired.

shopify.printing.print(src, options?)

src — prints the document at that URL.

options.printer Omitted → the system print dialog opens.
getPrinters() → pass a printer it returned → prints directly to that printer with no dialog.

Printer infoDescription
idPrinter identifier
namePrinter name
connectedConnection status. In practice, you generally pick the ones where connected is true

The Printing API is available on every POS UI extension target .

4Comparison with the legacy shopify.print

Itemshopify.print (deprecated)shopify.printing(2026-07~)
Enumerate printers No getPrinters() id / name / connected
Target a specific receipt printer No The dialog can't target a dedicated receipt printer Yes Print directly with no dialog
System print dialog Only option printer Omit it and it works as before
Status deprecated but no immediate action needed Recommended Migrate when you adopt 2026-07
Older API versions Earlier POS UI Extensions API versions areunchanged

5Rules for src and document formats

What you can pass to src

OK

The app's application_url -relative path

Example: '/print/receipt'

OK

A full same-origin URL

URLs on a different origin are not supported.

Documents are fetched using the extension's session token .

How each document format is handled

HTML

HTML

Receipt printers candirectly render.printer — pass it to print without a dialog.

Images

Like HTML, receipt printers can render these directly.

PDF

PDF

System print dialog required.src is a PDF and you pass printer , print throws an error. For PDFs, always use options.printer is omitted.

6Implementation pattern (fallback required)

getPrinters() returning an empty array is a case you must always handle by falling back to the system print dialog. This covers not only devices below POS 11.11.0, but alsomerchants who have no receipt printer .

const printers = await shopify.printing.getPrinters();
const receiptPrinter = printers.find((printer) => printer.connected);

if (receiptPrinter) {
 await shopify.printing.print('/print/receipt', {printer: receiptPrinter});
} else {
 await shopify.printing.print('/print/receipt');
}
1

Find printers

getPrinters() to fetch the list, then select the one whoseconnected is true.

2

If one exists, print directly

print(src, {printer}). The dialog never opens.

3

If none exists, the dialog

print(src) only. Legacy environments and stores without a printer still work this way.

Hardware printer discovery requires Shopify POS 11.11.0 or later. On earlier versions, even when a receipt printer is already paired, getPrinters() returns an empty array. Note that this limitation does not affect the system print dialog, which remains available.

How to verify

On a development store, set up POS 11.11.0 or later+a paired receipt printer , then usegetPrinters() to get a printer and pass it to shopify.printing.print .If it prints without showing the dialog, direct printing is working.

75 points engineers should keep in mind

11.11

1. An empty array is normal flow, not an error

On POS versions below 11.11.0, or in stores with no receipt printer, getPrinters() returns an empty array.Always write a branch that falls back to the dialog. Treating it as an exception will break printing in those environments.

PDF

2. A PDF combined with printer throws

src points to a PDF, passing printer will make shopify.printing.print throw an error.For PDFs, always leave options.printer outand let the dialog handle it. For receipts, HTML or images is the natural choice.

3. src has origin restrictions — fetch it with a token

The only thing you can pass is application_url a relative path from the root, ora full same-origin URL only. The fetch goes through the extension's session token, so the print endpoint should bedesigned to authenticate with that token and return the rendered result.

old new

4. Migrating at the same time you adopt 2026-07 is fine

shopify.print is deprecated, but no immediate action is needed. Earlier API versions are unchanged, so existing extensions keep working.Replacing it when you bump to 2026-07is the lowest-cost path.

5. Available on every target = you can put the print flow anywhere

The Printing API is all POS UI extension targets . You aren't tied to a specific screen, so you can place the print button wherever it fits your workflow — order details, cart, custom actions, and so on. Test on a development store with POS 11.11.0 or later and a paired receipt printer, and checkwhether it prints without showing a dialog.

8Three use cases you can put to work

USE CASE 1

Wipe out "print dialog hell" in in-store operations

Problem
Even with a dedicated receipt printer right next to the register, printing from a POS extension opened the system print dialog every time, forcing staff to re-select the output destination. And the dialog can't target a dedicated receipt printer in the first place.
Approach
Bump to 2026-07 and replace it with three lines: getPrinters()connected printer selection → print(src, {printer}) .
Result
Printing finishes in one tap. Shorter waits at the register, and no more redos caused by picking the wrong output destination.
Technical notes
Generate the receipt itself as HTML or an image (a PDF can't be printed directly). Always keep the dialog fallback for when the array is empty.
Older POS 11.11+ Dialog Direct print
USE CASE 2

Build printing that doesn't break in multi-store chains where device versions vary

Problem
POS app versions and printer configurations differ from store to store. The worry is that the moment you ship a new feature, printing stops working at stores on older devices.
Approach
getPrinters() returns an empty result — branch on that alone. Don't write version checks; just treatempty array = dialog as a single fallback covers both cases.
Impact
You can ship the feature without auditing device versions or waiting for every update to land. Stores with no printer run the same code.
Technical notes
Hardware discovery requires POS 11.11.0 or later. Below that you get an empty array even when a printer is paired, butthe system print dialog is still available, so the feature never breaks outright.
/print/label Printing
USE CASE 3

Print non-receipt in-store documents — layaway slips, repair tickets — straight from an extension

Problem
Staff prepare layaway and repair-intake copies on a separate device or by hand, cut off from the POS workflow.
Approach
In your app, expose a /print/<帳票> endpoint, then from a custom action in the POS UI extension call shopify.printing.print to send it to the same receipt printer.
Impact
Document printing collapses into a single POS action. The Printing API is available on every target, so you can put the print button on whatever screen fits the workflow.
Technical notes
src takes a path relative to application_url , or a same-origin URL. It isfetched with the extension's session token, so your endpoint should verify that token and return the HTML.

9One-line summary for your pitch

"POS UI Extensions 2026-07 introduces Printing API , enablingdirect, dialog-free printing to a receipt printerfrom an extension.
HTML and images print directly; PDFs still require the dialog. POS versions below 11.11.0 return an empty array, so a fallback is mandatory.
The legacy shopify.print is deprecated, but no immediate action is needed — migrate everything at once when you adopt 2026-07."