--- title: POS UI extensions description: | Build extensions that integrate into Shopify's Point of Sale interface. api_version: 2024-04 api_name: pos-ui-extensions source_url: html: 'https://shopify.dev/docs/api/pos-ui-extensions/2024-04' md: 'https://shopify.dev/docs/api/pos-ui-extensions/2024-04.md' --- # POS UI extensions Build extensions that integrate into [Shopify's Point of Sale](https://shopify.dev/docs/apps/build/pos) interface. For example, you can add a clickable tile to the POS home screen that launches your app's features, insert custom content sections into checkout and sales processes, or show additional product details. Extensions run in the context of key merchant workflows, so always prioritize performance. ## Getting started POS UI extensions require a set of essential files, including a TOML configuration file and JavaScript or TypeScript modules containing your extension code. Use [Shopify CLI](https://shopify.dev/docs/api/shopify-cli) to scaffold your extension with the essential configuration and files. You can alter the default configuration later to customize the way your POS UI extension operates. ## Generate scaffold ```terminal cd my-app shopify app generate extension ``` [Tutorial - Getting started with POS UI extensions](https://shopify.dev/docs/apps/build/pos/getting-started) *** ## Building your extension POS UI extensions are made up of three interconnected parts: **targets** that determine where your extension appears in the POS interface, **target APIs** that provide access to data and functionality based on your chosen target, and **UI components** that define which interface elements you can use. ### Targets: Choose where your extension appears Targets define where your extensions appear within Shopify's POS interface and what capabilities they have. There are three types of targets: | Target type | Description | | - | - | | Tile | Appear on the smart grid (homepage) of the POS system. Use to show status, quickly access common actions, and initiate workflows. | | Action | Trigger workflows and display modals. This target has two varieties, commonly used together: - **Menu item:** Add buttons to action menus on native POS screens. Use to provide entry points that launch modals. - **Modal:** Display full-screen interfaces for complete workflows, forms, or multi-step processes. Modals are launched from tiles or menu items. | | Block | Appear as inline content within native POS screens. Use to render content such as metrics or instructions. | [Reference - Explore all targets](https://shopify.dev/docs/api/pos-ui-extensions/2024-04/targets) ![Placeholder image](https://shopify.dev/images/templated-apis-screenshots/pos-ui-extensions/2024-04/pos-overview-targets.png) ### Target APIs: Define what your extension does Your extension might show customer loyalty points during checkout, add a custom "Print warranty card" action after completing a purchase, or capture additional product details when staff view inventory. Use Target APIs to access the data and functionality you need for each scenario—Session API for transaction details or other APIs for specific functionality. [Reference - Explore all target APIs](https://shopify.dev/docs/api/pos-ui-extensions/2024-04/target-apis) ## Session API: Retrieve current session data ##### React ```typescript import React, {useState} from 'react'; import { reactExtension, useApi, Screen, Text, } from '@shopify/ui-extensions-react/point-of-sale'; const SmartGridModal = () => { const {currentSession, getSessionToken} = useApi<'pos.home.modal.render'>().session; const {shopId, userId, locationId, staffMemberId} = currentSession; const [sessionToken, setSessionToken] = useState(); getSessionToken().then((newToken) => { setSessionToken(newToken); }); return ( shopId: {shopId}, userId: {userId}, locationId: {locationId}, staffId: {staffMemberId} sessionToken: {sessionToken} ); }; export default reactExtension('pos.home.modal.render', () => ( )); ``` ##### TypeScript ```typescript import { Screen, Stack, Text, extension, } from '@shopify/ui-extensions/point-of-sale'; export default extension('pos.home.modal.render', (root, api) => { const {session} = api; const {currentSession, getSessionToken} = session; const {shopId, userId, locationId, staffMemberId} = currentSession; const screen = root.createComponent(Screen, { name: 'ScreenOne', title: 'Screen One Title', }); const currentSessionText = root.createComponent( Text, {}, `shopId: ${shopId}, userId: ${userId}, locationId: ${locationId}, staffId: ${staffMemberId}`, ); const sessionTokenText = root.createComponent( Text, {}, 'sessionToken: undefined', ); getSessionToken().then((newToken) => { sessionTokenText.children.forEach((child) => { sessionTokenText.removeChild(child); }); sessionTokenText.appendChild(`sessionToken: ${newToken}`); }); screen.appendChild(currentSessionText); screen.appendChild(sessionTokenText); root.appendChild(screen); }); ``` ### UI components: Design your interface UI components are the building blocks that you use to display data and trigger API functions in POS UI extensions. These components follow [Shopify's design system](https://shopify.dev/docs/apps/design) and render optimized interfaces for retail workflows in [the POS app](https://apps.shopify.com/shopify-pos) on iOS and Android devices. Components are available as React components or JavaScript objects, imported from `@shopify/ui-extensions/point-of-sale`. The components are built with [remote-ui](https://github.com/Shopify/remote-dom), Shopify's library for building cross-platform user interfaces. Use UI components to build interfaces that automatically adapt across iOS and Android devices running Shopify POS. [Reference - Explore all UI components](https://shopify.dev/docs/api/pos-ui-extensions/2024-04/ui-components) ## Tile component: Render a tile on the smart grid ##### React ```typescript import React from 'react' import { Tile, reactExtension, useApi } from '@shopify/ui-extensions-react/point-of-sale' const TileComponent = () => { const api = useApi() return ( { api.action.presentModal() }} enabled /> ) } export default reactExtension('pos.home.tile.render', () => { return }) ``` ##### TypeScript ```typescript import { Tile, extension, } from '@shopify/ui-extensions/point-of-sale'; export default extension( 'pos.home.tile.render', (root, api) => { const tile = root.createComponent(Tile, { title: 'My app', subtitle: 'Hello world!', enabled: `true`, onPress: () => { api.action.presentModal(); }, }); root.append(tile); }, ); ``` ![Placeholder image](https://shopify.dev/images/templated-apis-screenshots/pos-ui-extensions/2024-04/tile-default.png) *** ## Configuration POS UI extensions rely on a `shopify.extension.toml` file that contains the extension's configuration. This includes the extension name, type, API version, and targeting definitions. The `name` value is what displays in the POS interface to merchants, so consider this value carefully. We recommend that the `api_version` reflects the latest supported API version. ### Properties POS UI extensions use the following configuration properties: ##### `api_version` required The version of the API that's being used for the extension. If provided in the `[[extensions]]` array, then the specified API version is used instead of the root level `api_version`. ##### `[[extensions]]` required The name of the array that contains all extensions listed in the TOML file. Contains the following properties: * `type`: required The extension type. For more information, refer to [Extension types](https://shopify.dev/docs/apps/build/app-extensions/configure-app-extensions#extension-types). * `name`: required The merchant-facing name of the extension. After you [generate an extension](https://shopify.dev/docs/api/shopify-cli/app/app-generate-extension), you're prompted to provide a name for your extension. The `name` property is translatable if it starts with a `t:` and uses a key defined in your translation data. For example, you might have a `t:name` key that matches a translation key called `name`. [Learn more about localization](https://shopify.dev/docs/apps/build/checkout/localized-checkout-ui-extensions#how-it-works). * `handle`: required The unique internal identifier for the extension. After you create a draft version of the extension, or deploy an extension, you can't change the `handle` value. If not specified, the `handle` value is automatically populated using a transformed `name` value that removes any unsupported characters. For example, if you enter `google maps` as the extension name, then Shopify populates the `handle` value as `google-maps`. * `description`: required The merchant-facing description of the extension. The `description` property is translatable if it starts with a `t:` and uses a key defined in your translation data. For example, `t:description` and you have a matching translation key called `description`. [Learn more about localization](https://shopify.dev/docs/apps/build/checkout/localized-checkout-ui-extensions#how-it-works). ##### `[[extensions.targeting]]` required The name of the array that contains a target and its associated module. Contains the following properties: * `target`: required An identifier that specifies where you're injecting your extension into the POS interface. * `module`: required The path to the JavaScript or TypeScript file that contains your extension code. This file exports the extension function that renders your UI or handles events. ## shopify.extension.toml ```toml api_version = "" [[extensions]] type = "ui_extension" name = "My POS UI extension" handle = "my-pos-ui-extension" description = "My POS UI extension description" [[extensions.targeting]] target = "pos.home.tile.render" module = "./src/Tile.tsx" [[extensions.targeting]] target = "pos.home.modal.render" module = "./src/Modal.tsx" ``` *** ## Testing and deployment After you've built your extension, test it thoroughly and deploy it to production. Testing POS UI extensions requires a [development store](https://shopify.dev/docs/api/development-stores) and the [Shopify POS app](https://www.shopify.com/pos/pos-app) on any mobile or tablet device—no dedicated POS hardware needed. Download the POS app from the [App Store](https://apps.apple.com/app/shopify-point-of-sale-pos/id1087750983) or [Google Play](https://play.google.com/store/apps/details?id=com.shopify.pos), log in to your development store, and start testing. Extensions run in preview mode during development, allowing you to test functionality and iterate quickly without affecting live merchant operations. Use [Shopify CLI](https://shopify.dev/docs/api/shopify-cli) to deploy your app and its extensions to production. [Tutorial - Debugging POS UI extensions](https://shopify.dev/docs/apps/build/pos/debugging) [Tutorial - Troubleshooting POS UI extensions](https://shopify.dev/docs/apps/build/pos/troubleshooting) ## Deploy your extension ```terminal cd my-app npm run deploy ``` *** ## Tutorials and resources Deepen your understanding of POS UI extensions with these tutorials and community resources. ### Tutorials [Tutorial - Getting started with POS UI extensions](https://shopify.dev/docs/apps/build/pos/getting-started) [Tutorial - Build a discount extension](https://shopify.dev/docs/apps/build/pos/build-discount-extension) [Tutorial - Communicate with a server](https://shopify.dev/docs/apps/build/pos/communicate-with-server) ### Community resources [Reference - Developer changelog for POS UI extensions](https://shopify.dev/changelog?filter=pos-extensions) [Community - Community forum for POS UI extensions](https://community.shopify.dev/tag/pos-extensions) ***