---
title: Printing API
description: >-
  The Printing API lets POS UI extensions discover connected hardware printers
  and print documents through a selected printer or the system print dialog.
api_version: 2026-07
source_url:
  html: >-
    https://shopify.dev/docs/api/pos-ui-extensions/latest/target-apis/platform-apis/printing-api
  md: >-
    https://shopify.dev/docs/api/pos-ui-extensions/latest/target-apis/platform-apis/printing-api.md
api_name: pos-ui-extensions
---

# Printing API

The Printing API lets POS UI extensions print documents from your app backend. Use it for receipts, labels, slips, and other printable content.

### Use cases

* **Direct printer jobs:** Send HTML or image receipts directly to a connected hardware printer.
* **Labels and slips:** Print labels, pickup slips, or packing slips without opening the system print dialog.
* **Dialog fallback:** Show the system print dialog when no hardware printer is selected.

### Support Targets (22)

### Supported targets

* [pos.​cart.​line-item-details.​action.​menu-item.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-07/targets/cart-details#cart-details-targets)
* [pos.​cart.​line-item-details.​action.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-07/targets/cart-details#cart-details-action-modal-)
* [pos.​customer-details.​action.​menu-item.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-07/targets/customer-details#customer-details-action-menu-item-)
* [pos.​customer-details.​action.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-07/targets/customer-details#customer-details-action-modal-)
* [pos.​customer-details.​block.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-07/targets/customer-details#customer-details-targets)
* [pos.​draft-order-details.​action.​menu-item.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-07/targets/draft-order-details#draft-order-details-action-menu-item-)
* [pos.​draft-order-details.​action.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-07/targets/draft-order-details#draft-order-details-action-modal-)
* [pos.​draft-order-details.​block.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-07/targets/draft-order-details#draft-order-details-targets)
* [pos.​home.​modal.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-07/targets/home-screen#home-screen-action-modal-)
* [pos.​home.​tile.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-07/targets/home-screen#home-screen-targets)
* [pos.​order-details.​action.​menu-item.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-07/targets/order-details#order-details-action-menu-item-)
* [pos.​order-details.​action.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-07/targets/order-details#order-details-action-modal-)
* [pos.​order-details.​block.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-07/targets/order-details#order-details-targets)
* [pos.​product-details.​action.​menu-item.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-07/targets/product-details#product-details-action-menu-item-)
* [pos.​product-details.​action.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-07/targets/product-details#product-details-action-modal-)
* [pos.​product-details.​block.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-07/targets/product-details#product-details-targets)
* [pos.​purchase.​post.​action.​menu-item.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-07/targets/post-purchase#post-purchase-action-menu-item-)
* [pos.​purchase.​post.​action.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-07/targets/post-purchase#post-purchase-action-modal-)
* [pos.​purchase.​post.​block.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-07/targets/post-purchase#post-purchase-targets)
* [pos.​register-details.​action.​menu-item.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-07/targets/register-details#register-details-targets)
* [pos.​register-details.​action.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-07/targets/register-details#register-details-action-modal-)
* [pos.​register-details.​block.​render](https://shopify.dev/docs/api/pos-ui-extensions/2026-07/targets/register-details#register-details-block-)

### Properties

The [`shopify` global object](https://shopify.dev/docs/api/pos-ui-extensions/latest#target-apis-define-what-your-extension-does) provides methods for discovering hardware printers and printing documents. Access the following properties on `shopify.printing` to list printers or print HTML, image, and PDF content.

* **getPrinters**

  **() => Promise\<Printer\[]>**

  **required**

  Returns the list of hardware printers currently available to the device. Each printer includes its connection status and a reference that can be passed to `print()`.

  When no hardware printers are available, returns an empty array. The system print dialog is not included in this list — it is the default behavior when no `printer` option is provided to `print()`.

* **print**

  **(src: string, options?: PrintOptions) => Promise\<void>**

  **required**

  Triggers a print operation for the specified document source.

  When called without a `printer` option, opens the device's system print dialog (e.g., AirPrint on iOS, Android print service). When a `printer` reference is provided (from `getPrinters()`), sends the content directly to that printer without showing a dialog.

  The `src` parameter accepts either:

  * A relative path that will be appended to your app's [`application_url`](https://shopify.dev/docs/apps/build/cli-for-apps/app-configuration)
  * A full URL to your app's backend

  The content at the URL is fetched with the extension's session token for authentication. HTML, PDFs, and images are supported content types. PDFs can only be printed via the system print dialog: selecting a `printer` with a PDF `src` throws, because hardware (receipt) printers render HTML and image content only.

### Printer

A hardware printer available to the device, as returned by \`shopify.printing.getPrinters()\`.

* connected

  Whether the printer is currently able to accept print jobs.

  ```ts
  boolean
  ```

* id

  Unique identifier for this printer.

  ```ts
  string
  ```

* name

  Human-readable display name (e.g., "Star TSP143" or "Front Counter Printer").

  ```ts
  string
  ```

### PrintOptions

Options for \`shopify.printing.print()\`.

* printer

  A printer reference obtained from \`getPrinters()\`. When provided, the print job is sent directly to this printer without showing a system print dialog. When omitted, the system print dialog is shown, allowing the user to select a printer and configure print settings.

  ```ts
  Printer
  ```

Examples

### Examples

* ####

  ##### Description

  Call \`shopify.printing.print()\` without a \`printer\` option to open the system print dialog from a POS tile.

  ##### jsx

  ```tsx
  import {render} from 'preact';

  export default async () => {
    render(<Extension />, document.body);
  };

  const Extension = () => {
    return (
      <s-tile
        heading="My app"
        subheading="Print document"
        onClick={() => {
          shopify.printing.print('documents/test-print');
        }}
      />
    );
  };
  ```

* ####

  ##### Description

  Print documents hosted by your app backend using a full URL.

  ##### jsx

  ```tsx
  import {render} from 'preact';

  export default async () => {
    render(<Extension />, document.body);
  };

  const Extension = () => {
    return (
      <s-tile
        heading="My app"
        subheading="Print with full URL"
        onClick={async () => {
          await shopify.printing.print(
            'https://my-print-service.com/api/print/document',
          );
        }}
      />
    );
  };
  ```

* ####

  ##### Description

  Print documents using a path relative to your app's \`application\_url\`.

  ##### jsx

  ```tsx
  import {render} from 'preact';

  export default async () => {
    render(<Extension />, document.body);
  };

  const Extension = () => {
    return (
      <s-tile
        heading="My app"
        subheading="Print with relative path"
        onClick={async () => {
          await shopify.printing.print('/api/print/document');
        }}
      />
    );
  };
  ```

* ####

  ##### Description

  Find a connected hardware printer and send a receipt directly to it. If none is connected, fall back to the system print dialog.

  ##### jsx

  ```tsx
  import {render} from 'preact';

  export default async () => {
    render(<Extension />, document.body);
  };

  const Extension = () => {
    async function printReceipt() {
      try {
        const printers = await shopify.printing.getPrinters();
        const receiptPrinter = printers.find((printer) => printer.connected);

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

        await shopify.printing.print('/print/receipt');
      } catch (error) {
        console.error('Unable to print receipt', error);
      }
    }

    return (
      <s-tile
        heading="Print receipt"
        subheading="Use receipt printer"
        onClick={printReceipt}
      />
    );
  };
  ```

***

## Best practices

* Check `printer.connected` before sending a direct print job.
* Keep direct-print documents simple. Use HTML or images sized for the target printer.
* Use the system print dialog for PDFs.
* Show a clear fallback when no hardware printer is available.

***

## Limitations

* The `src` passed to `print()` must use the same origin as your app's `application_url`.
* `getPrinters()` returns hardware printers only. The system print dialog isn't included in that list.
* Direct printing requires a connected `Printer` returned by `getPrinters()`.
* PDFs can only be printed through the system print dialog. Passing a `printer` with a PDF `src` throws an error.

***
