The Scanner API enables an extension to access scanner data and available scanning sources supported by the device. ### Supporting targets - [pos.home.modal.render](/docs/api/pos-ui-extensions/targets/smart-grid/pos-home-modal-render) - [pos.purchase.post.action.render](/docs/api/pos-ui-extensions/targets/post-purchase/pos-purchase-post-action-render) - [pos.product-details.action.render](/docs/api/pos-ui-extensions/targets/product-details/pos-product-details-action-render) - [pos.order-details.action.render](/docs/api/pos-ui-extensions/targets/order-details/pos-order-details-action-render) - [pos.draft-order-details.action.render](/docs/api/pos-ui-extensions/targets/draft-order-details/pos-draft-order-details-action-render) - [pos.customer-details.action.menu-item.render](/docs/api/pos-ui-extensions/targets/customer-details/pos-customer-details-action-menu-item-render)
Creates a subscription to scan events Provides an initial value and a callback to subscribe to value changes. Currently supports only one subscription. You can utilize `makeStatefulSubscribable` on a `RemoteSubscribable` to implement multiple subscriptions. Using `makeStatefulSubscribable` or the corresponding hooks counts as a subscription.
Creates a subscription to the scanning sources available on the POS device. Provides an initial value and a callback to subscribe to value changes. Currently supports only one subscription. You can utilize `makeStatefulSubscribable` on a `RemoteSubscribable` to implement multiple subscriptions. Using `makeStatefulSubscribable` or the corresponding hooks counts as a subscription.
The string data from the last scanner event received.
The scanning source from which the scan event came.
The scanner source the POS device supports.
'camera' | 'external' | 'embedded'
The Scanner API enables an extension to access scanner data and available scanning sources supported by the device. ### Supporting targets - [pos.home.modal.render](/docs/api/pos-ui-extensions/targets/smart-grid/pos-home-modal-render) - [pos.purchase.post.action.render](/docs/api/pos-ui-extensions/targets/post-purchase/pos-purchase-post-action-render) - [pos.product-details.action.render](/docs/api/pos-ui-extensions/targets/product-details/pos-product-details-action-render) - [pos.order-details.action.render](/docs/api/pos-ui-extensions/targets/order-details/pos-order-details-action-render) - [pos.draft-order-details.action.render](/docs/api/pos-ui-extensions/targets/draft-order-details/pos-draft-order-details-action-render) - [pos.customer-details.action.menu-item.render](/docs/api/pos-ui-extensions/targets/customer-details/pos-customer-details-action-menu-item-render)
import React from 'react';
import {
Navigator,
Screen,
Stack,
Text,
useScannerDataSubscription,
reactExtension,
} from '@shopify/ui-extensions-react/point-of-sale';
const SmartGridModal = () => {
const {data, source} = useScannerDataSubscription();
return (
<Navigator>
<Screen name="Home" title="Home">
<Stack direction="horizontal">
<Text>{`Scanned data: ${data || ''} with ${source || ''}`}</Text>
</Stack>
</Screen>
</Navigator>
);
};
export default reactExtension('pos.home.modal.render', () => (
<SmartGridModal />
));
import {
Navigator,
Screen,
Stack,
Text,
extension,
} from '@shopify/ui-extensions/point-of-sale';
export default extension('pos.home.modal.render', (root, api) => {
const dataText = root.createComponent('Text', null, 'Scanned data: ');
const sourceText = root.createComponent(
'Text',
null,
'Scanned data source: ',
);
const stack1 = root.createComponent(Stack, {
direction: 'horizontal',
});
const screen = root.createComponent(Screen, {
title: 'Home',
name: 'Home',
});
const navigator = root.createComponent(Navigator);
stack1.append(dataText);
stack1.append(sourceText);
screen.append(stack1);
navigator.append(screen);
root.append(navigator);
api.scanner.scannerDataSubscribable.subscribe((data, source) => {
dataText.replaceChildren(`Scanned data: ${data || ''}`);
sourceText.updateProps(`Scanned data source: ${source || ''}`);
});
});
import React from 'react';
import {
Navigator,
Screen,
Stack,
Text,
useScannerDataSubscription,
reactExtension,
} from '@shopify/ui-extensions-react/point-of-sale';
const SmartGridModal = () => {
const {data, source} = useScannerDataSubscription();
return (
<Navigator>
<Screen name="Home" title="Home">
<Stack direction="horizontal">
<Text>{`Scanned data: ${data || ''} with ${source || ''}`}</Text>
</Stack>
</Screen>
</Navigator>
);
};
export default reactExtension('pos.home.modal.render', () => (
<SmartGridModal />
));
import {
Navigator,
Screen,
Stack,
Text,
extension,
} from '@shopify/ui-extensions/point-of-sale';
export default extension('pos.home.modal.render', (root, api) => {
const dataText = root.createComponent('Text', null, 'Scanned data: ');
const sourceText = root.createComponent(
'Text',
null,
'Scanned data source: ',
);
const stack1 = root.createComponent(Stack, {
direction: 'horizontal',
});
const screen = root.createComponent(Screen, {
title: 'Home',
name: 'Home',
});
const navigator = root.createComponent(Navigator);
stack1.append(dataText);
stack1.append(sourceText);
screen.append(stack1);
navigator.append(screen);
root.append(navigator);
api.scanner.scannerDataSubscribable.subscribe((data, source) => {
dataText.replaceChildren(`Scanned data: ${data || ''}`);
sourceText.updateProps(`Scanned data source: ${source || ''}`);
});
});
import React from 'react';
import {
Navigator,
Screen,
Stack,
Text,
useScannerSourcesSubscription,
reactExtension,
} from '@shopify/ui-extensions-react/point-of-sale';
const SmartGridModal = () => {
const scannerSources = useScannerSourcesSubscription();
return (
<Navigator>
<Screen name="Home" title="Home">
<Stack direction="horizontal">
<Text>{`Available scanner sources: ${scannerSources}`}</Text>
</Stack>
</Screen>
</Navigator>
);
};
export default reactExtension('pos.home.modal.render', () => (
<SmartGridModal />
));
import {
Navigator,
Screen,
Stack,
Text,
extension,
} from '@shopify/ui-extensions/point-of-sale';
export default extension('pos.home.modal.render', (root, api) => {
const scannerSourcesText = root.createComponent(
'Text',
null,
'Available scanner sources: ',
);
const stack1 = root.createComponent(Stack, {
direction: 'horizontal',
});
const screen = root.createComponent(Screen, {
title: 'Home',
name: 'Home',
});
const navigator = root.createComponent(Navigator);
stack1.append(scannerSourcesText);
screen.append(stack1);
navigator.append(screen);
root.append(navigator);
api.scanner.scannerSourcesSubscribable.subscribe((sources) => {
scannerSourcesText.replaceChildren(`Available scanner sources: ${sources}`);
});
});
import React from 'react';
import {
Navigator,
Screen,
Stack,
Text,
useScannerSourcesSubscription,
reactExtension,
} from '@shopify/ui-extensions-react/point-of-sale';
const SmartGridModal = () => {
const scannerSources = useScannerSourcesSubscription();
return (
<Navigator>
<Screen name="Home" title="Home">
<Stack direction="horizontal">
<Text>{`Available scanner sources: ${scannerSources}`}</Text>
</Stack>
</Screen>
</Navigator>
);
};
export default reactExtension('pos.home.modal.render', () => (
<SmartGridModal />
));
import {
Navigator,
Screen,
Stack,
Text,
extension,
} from '@shopify/ui-extensions/point-of-sale';
export default extension('pos.home.modal.render', (root, api) => {
const scannerSourcesText = root.createComponent(
'Text',
null,
'Available scanner sources: ',
);
const stack1 = root.createComponent(Stack, {
direction: 'horizontal',
});
const screen = root.createComponent(Screen, {
title: 'Home',
name: 'Home',
});
const navigator = root.createComponent(Navigator);
stack1.append(scannerSourcesText);
screen.append(stack1);
navigator.append(screen);
root.append(navigator);
api.scanner.scannerSourcesSubscribable.subscribe((sources) => {
scannerSourcesText.replaceChildren(`Available scanner sources: ${sources}`);
});
});
import React from 'react';
import {
Navigator,
Screen,
Stack,
Text,
useScannerDataSubscription,
useApi,
reactExtension,
} from '@shopify/ui-extensions-react/point-of-sale';
const SmartGridModal = () => {
const api = useApi<'pos.home.modal.render'>();
const {data} = useScannerDataSubscription();
return (
<Navigator>
<Screen name="Home" title="Home">
<Stack direction="horizontal">
<Text>{`Scanned data: ${data || ''}`}</Text>
</Stack>
</Screen>
</Navigator>
);
};
export default reactExtension('pos.home.modal.render', () => (
<SmartGridModal />
));
import React from 'react';
import {
Navigator,
Screen,
Stack,
Text,
extension,
} from '@shopify/ui-extensions/point-of-sale';
export default extension('pos.home.modal.render', (root, api) => {
const text = root.createComponent('Text', null, 'Scanned data: ');
const stack = root.createComponent(Stack, {
direction: 'horizontal',
});
const screen = root.createComponent(Screen, {
title: 'Home',
name: 'Home',
});
const navigator = root.createComponent(Navigator);
stack.append(text);
screen.append(stack);
navigator.append(screen);
root.append(navigator);
api.scanner.scannerDataSubscribable.subscribe((data) => {
text.replaceChildren(`Scanned data: ${data || ''}`);
});
});
import React from 'react';
import {
CameraScanner,
Navigator,
Screen,
Stack,
Text,
useScannerDataSubscription,
useScannerSourcesSubscription,
reactExtension,
} from '@shopify/ui-extensions-react/point-of-sale';
const SmartGridModal = () => {
const {data, source} = useScannerDataSubscription();
const availableScanners = useScannerSourcesSubscription();
const hasCameraScanner = availableScanners.includes('camera');
return (
<Navigator>
<Screen name="Home" title="Home">
<Stack direction="horizontal">
{hasCameraScanner ? (
<CameraScanner />
) : (
<Stack direction="vertical" alignment="space-evenly">
<Text>{`Scanned data: ${data || ''}`}</Text>
<Text>{`Scanned data source: ${source || ''}`}</Text>
</Stack>
)}
</Stack>
</Screen>
</Navigator>
);
};
export default reactExtension('pos.home.modal.render', () => (
<SmartGridModal />
));
import {
CameraScanner,
Navigator,
Screen,
Stack,
Text,
extension,
} from '@shopify/ui-extensions/point-of-sale';
export default extension('pos.home.modal.render', (root, api) => {
const dataText = root.createComponent('Text', null, 'Scanned data: ');
const sourceText = root.createComponent(
'Text',
null,
'Scanned data source: ',
);
const cameraScanner = root.createComponent(CameraScanner);
const stack1 = root.createComponent(Stack, {
direction: 'horizontal',
});
const stack2 = root.createComponent(Stack, {
direction: 'vertical',
alignment: 'space-evenly',
});
const screen = root.createComponent(Screen, {
title: 'Home',
name: 'Home',
});
const navigator = root.createComponent(Navigator);
screen.append(stack1);
navigator.append(screen);
root.append(navigator);
api.scanner.scannerDataSubscribable.subscribe((data, source) => {
dataText.replaceChildren(`Scanned data: ${data || ''}`);
sourceText.replaceChildren(`Scanned data source: ${source || ''}`);
});
api.scanner.scannerSourcesSubscribable.subscribe((sources) => {
// Clear previous children to avoid duplicate appending
stack1.children = [];
stack2.children = [];
if (sources.include('camera')) {
stack1.append(cameraScanner);
} else {
stack2.append(dataText);
stack2.append(sourceText);
stack1.append(stack2);
}
});
});