shopify-pos

Shopify POS UI Extensions (2026)

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "shopify-pos" with this command: npx skills add toilahuongg/shopify-agents-kit/toilahuongg-shopify-agents-kit-shopify-pos

Shopify POS UI Extensions (2026)

Build custom extensions that integrate directly into Shopify's Point of Sale interface on iOS and Android devices.

Official References

  • POS UI Extensions API

  • Building for POS

  • POS Extension Targets

Prerequisites

  • Shopify CLI (latest)

  • Shopify App with POS enabled

  • Development store with POS Pro subscription

Enable POS embedding: In Partner Dashboard > App > Configuration, set "Embed app in Shopify POS" to True.

Extension Architecture

POS UI extensions have three interconnected parts:

  • Targets - Where your extension appears (tile, modal, block, menu item)

  • Target APIs - Data and functionality access (Cart, Customer, Session, etc.)

  • Components - Native UI building blocks (Button, Screen, List, etc.)

Creating a POS Extension

shopify app generate extension --template pos_ui --name "my-pos-extension"

Configuration (shopify.extension.toml)

api_version = "2025-10"

[[extensions]] type = "ui_extension" name = "my-pos-extension" handle = "my-pos-extension"

[[extensions.targeting]] module = "./src/Tile.tsx" target = "pos.home.tile.render"

[[extensions.targeting]] module = "./src/Modal.tsx" target = "pos.home.modal.render"

Targets Reference

See references/targets.md for all available targets.

Target Types

Type Purpose Example

Tile Smart grid button on home screen pos.home.tile.render

Modal Full-screen interface pos.home.modal.render

Block Inline content section pos.product-details.block.render

Menu Item Action menu button pos.customer-details.action.menu-item.render

Common Target Patterns

Home Screen (Smart Grid)

// Tile.tsx - Entry point on POS home import { Tile, reactExtension } from '@shopify/ui-extensions-react/point-of-sale';

export default reactExtension('pos.home.tile.render', () => <TileComponent />);

function TileComponent() { return <Tile title="My App" subtitle="Tap to open" enabled={true} />; }

Modal (Full Screen)

// Modal.tsx - Launches when tile is tapped import { Screen, Navigator, Text, Button, useApi, reactExtension } from '@shopify/ui-extensions-react/point-of-sale';

export default reactExtension('pos.home.modal.render', () => <ModalComponent />);

function ModalComponent() { const api = useApi<'pos.home.modal.render'>();

return ( <Navigator> <Screen name="Main" title="My Extension"> <Text>Welcome to my POS extension</Text> <Button title="Close" onPress={() => api.navigation.dismiss()} /> </Screen> </Navigator> ); }

Block (Inline Content)

// ProductBlock.tsx import { Section, Text, reactExtension, useApi } from '@shopify/ui-extensions-react/point-of-sale';

export default reactExtension('pos.product-details.block.render', () => <ProductBlock />);

function ProductBlock() { const { product } = useApi<'pos.product-details.block.render'>(); const productData = product.getProduct();

return ( <Section title="Custom Info"> <Text>Product ID: {productData?.id}</Text> </Section> ); }

Components Reference

See references/components.md for all available components.

Key Components

Layout & Structure

  • Screen

  • Navigation screen with title, loading state, actions

  • Navigator

  • Screen navigation container

  • ScrollView

  • Scrollable content container

  • Section

  • Card-like grouping container

  • Stack

  • Horizontal/vertical layout

  • List

  • Structured data rows

Actions

  • Button

  • Tappable action button

  • Tile

  • Smart grid tile (home screen only)

  • Selectable

  • Make components tappable

Forms

  • TextField , TextArea

  • Text input

  • NumberField

  • Numeric input

  • EmailField

  • Email with validation

  • DateField , DatePicker

  • Date selection

  • RadioButtonList

  • Single selection

  • Stepper

  • Increment/decrement control

  • PinPad

  • Secure PIN entry

Feedback

  • Banner

  • Important messages

  • Dialog

  • Confirmation prompts

  • Badge

  • Status indicators

Media

  • Icon

  • POS icon catalog

  • Image

  • Visual content

  • CameraScanner

  • Barcode/QR scanning

APIs Reference

See references/apis.md for all available APIs.

Accessing APIs

import { useApi } from '@shopify/ui-extensions-react/point-of-sale';

function MyComponent() { const api = useApi<'pos.home.modal.render'>();

// Access various APIs based on target const { cart, customer, session, navigation, toast } = api; }

Core APIs

Cart API - Modify cart contents

const { cart } = useApi<'pos.home.modal.render'>();

// Add item await cart.addLineItem({ variantId: 'gid://shopify/ProductVariant/123', quantity: 1 });

// Apply discount await cart.applyCartDiscount({ type: 'percentage', value: 10, title: '10% Off' });

// Get cart const currentCart = cart.getCart();

Session API - Authentication and session data

const { session } = useApi<'pos.home.modal.render'>();

// Get session token for backend auth const token = await session.getSessionToken();

// Get current staff member const staff = session.currentSession;

Customer API - Customer data access

const { customer } = useApi<'pos.customer-details.block.render'>(); const customerData = customer.getCustomer();

Toast API - Show notifications

const { toast } = useApi<'pos.home.modal.render'>(); toast.show('Item added successfully');

Navigation API - Screen navigation

const { navigation } = useApi<'pos.home.modal.render'>(); navigation.dismiss(); // Close modal navigation.navigate('ScreenName'); // Navigate to screen

Scanner API - Barcode scanning

const { scanner } = useApi<'pos.home.modal.render'>(); const result = await scanner.scanBarcode();

Print API - Receipt printing

const { print } = useApi<'pos.home.modal.render'>(); await print.printDocument(documentContent);

Direct GraphQL API Access

Available for extensions targeting 2025-07 or later (requires POS 10.6.0+).

const response = await fetch('shopify:admin/api/graphql.json', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query: query GetProduct($id: ID!) { product(id: $id) { title variants(first: 10) { nodes { id title inventoryQuantity } } } } , variables: { id: 'gid://shopify/Product/123' } }) });

Declare required scopes in shopify.app.toml :

[access_scopes] scopes = "read_products,write_products,read_customers"

Development Workflow

Local Development

shopify app dev

Open the Shopify POS app on your device and connect to the development store.

Testing

  • Install app on development store

  • Open Shopify POS app

  • Navigate to smart grid (home) to see tiles

  • Tap tiles to test modals

  • Navigate to relevant screens (products, customers, orders) for block/action targets

Deployment

shopify app deploy

Best Practices

  • Performance First - Extensions run in critical merchant workflows; minimize API calls and computations

  • Offline Consideration - Use Storage API for data that should persist offline

  • Native Feel - Use provided components to match POS design system

  • Error Handling - Always handle API failures gracefully with user feedback

  • Loading States - Show loading indicators during async operations

Storage API for Offline Data

const { storage } = useApi<'pos.home.modal.render'>();

// Store data await storage.setItem('key', JSON.stringify(data));

// Retrieve data const stored = await storage.getItem('key'); const data = stored ? JSON.parse(stored) : null;

Complete Example: Loyalty Points Extension

// Tile.tsx import { Tile, reactExtension } from '@shopify/ui-extensions-react/point-of-sale';

export default reactExtension('pos.home.tile.render', () => ( <Tile title="Loyalty Points" subtitle="Check & redeem" enabled={true} /> ));

// Modal.tsx import { Screen, Navigator, Text, Button, Section, Stack, useApi, reactExtension } from '@shopify/ui-extensions-react/point-of-sale'; import { useState, useEffect } from 'react';

export default reactExtension('pos.home.modal.render', () => <LoyaltyModal />);

function LoyaltyModal() { const { cart, session, navigation, toast } = useApi<'pos.home.modal.render'>(); const [points, setPoints] = useState(0); const [loading, setLoading] = useState(true);

useEffect(() => { fetchPoints(); }, []);

async function fetchPoints() { const token = await session.getSessionToken(); const currentCart = cart.getCart(); const customerId = currentCart?.customer?.id;

if (!customerId) {
  setLoading(false);
  return;
}

const res = await fetch('https://your-backend.com/api/points', {
  headers: { Authorization: `Bearer ${token}` },
  body: JSON.stringify({ customerId })
});
const data = await res.json();
setPoints(data.points);
setLoading(false);

}

async function redeemPoints() { await cart.applyCartDiscount({ type: 'fixedAmount', value: points / 100, title: 'Loyalty Redemption' }); toast.show('Points redeemed!'); navigation.dismiss(); }

return ( <Navigator> <Screen name="Main" title="Loyalty Points" isLoading={loading}> <Section title="Current Balance"> <Stack direction="vertical" spacing={2}> <Text variant="headingLarge">{points} points</Text> <Text>Worth ${(points / 100).toFixed(2)}</Text> </Stack> </Section> <Button title="Redeem All Points" type="primary" onPress={redeemPoints} disabled={points === 0} /> <Button title="Close" onPress={() => navigation.dismiss()} /> </Screen> </Navigator> ); }

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Automation

shopify-polaris-icons

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

shopify-polaris-viz

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

shopify-api

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

shopify-extensions

No summary provided by upstream source.

Repository SourceNeeds Review