From 5c88ebf02292b249c4abc4f6d0058a4a3c6551f7 Mon Sep 17 00:00:00 2001 From: Monorail CI check running in Buildkite Date: Tue, 30 Jun 2026 18:12:50 -0700 Subject: [PATCH 1/2] Add POS background extension template Assisted-By: devx/ad8a9826-c8c5-4579-8ce6-44cd1b431ab4 --- pos-background/README.md | 8 ++++ pos-background/package.json.liquid | 9 ++++ pos-background/shopify.extension.toml.liquid | 12 +++++ .../src/background-extension.liquid | 46 +++++++++++++++++++ pos-background/tsconfig.json.liquid | 12 +++++ templates.json | 23 ++++++++++ 6 files changed, 110 insertions(+) create mode 100644 pos-background/README.md create mode 100644 pos-background/package.json.liquid create mode 100644 pos-background/shopify.extension.toml.liquid create mode 100644 pos-background/src/background-extension.liquid create mode 100644 pos-background/tsconfig.json.liquid diff --git a/pos-background/README.md b/pos-background/README.md new file mode 100644 index 00000000..d5ea2bb0 --- /dev/null +++ b/pos-background/README.md @@ -0,0 +1,8 @@ +# POS background extension + +Scaffold for a non-visual POS background extension targeting `pos.app.ready.data`. + +The background target runs for the full POS session and observes events via +`shopify.addEventListener()`. It does not render UI. See the example handlers in +`src/background-extension.{js,ts}` for `transactioncomplete`, +`cashtrackingsessionstart`, and `cashtrackingsessioncomplete`. diff --git a/pos-background/package.json.liquid b/pos-background/package.json.liquid new file mode 100644 index 00000000..69c5bedf --- /dev/null +++ b/pos-background/package.json.liquid @@ -0,0 +1,9 @@ +{ + "name": "{{ handle }}", + "private": true, + "version": "1.0.0", + "license": "UNLICENSED", + "dependencies": { + "@shopify/ui-extensions": "2026.7.x" + } +} diff --git a/pos-background/shopify.extension.toml.liquid b/pos-background/shopify.extension.toml.liquid new file mode 100644 index 00000000..1658c75b --- /dev/null +++ b/pos-background/shopify.extension.toml.liquid @@ -0,0 +1,12 @@ +api_version = "2026-07" + +[[extensions]] +type = "ui_extension" +name = "{{ name }}" +{% if uid %}uid = "{{ uid }}"{% endif %} +handle = "{{ handle }}" +description = "A {{ flavor }} POS background extension" + +[[extensions.targeting]] +module = "./src/background-extension.{{ srcFileExtension }}" +target = "pos.app.ready.data" diff --git a/pos-background/src/background-extension.liquid b/pos-background/src/background-extension.liquid new file mode 100644 index 00000000..733058c5 --- /dev/null +++ b/pos-background/src/background-extension.liquid @@ -0,0 +1,46 @@ +import { POS_EVENT_NAMES } from '@shopify/ui-extensions/point-of-sale'; +{% if flavor contains "typescript" %} +import type { + TransactionCompleteEvent, + CashTrackingSessionStartEvent, + CashTrackingSessionCompleteEvent, +} from '@shopify/ui-extensions/point-of-sale'; +import type { Api } from '@shopify/ui-extensions/pos.app.ready.data'; +{% endif %} + +export default ({% if flavor contains "typescript" %}api: Api{% else %}_api{% endif %}) => { + console.log('background extension started'); + + shopify.addEventListener( + POS_EVENT_NAMES.TRANSACTION_COMPLETE, + (event{% if flavor contains "typescript" %}: TransactionCompleteEvent{% endif %}) => { + try { + console.log('transaction complete', event); + } catch (error) { + console.error('transaction complete handler failed', error); + } + }, + ); + + shopify.addEventListener( + POS_EVENT_NAMES.CASH_TRACKING_SESSION_START, + (event{% if flavor contains "typescript" %}: CashTrackingSessionStartEvent{% endif %}) => { + try { + console.log('cash tracking session start', event); + } catch (error) { + console.error('cash tracking session start handler failed', error); + } + }, + ); + + shopify.addEventListener( + POS_EVENT_NAMES.CASH_TRACKING_SESSION_COMPLETE, + (event{% if flavor contains "typescript" %}: CashTrackingSessionCompleteEvent{% endif %}) => { + try { + console.log('cash tracking session complete', event); + } catch (error) { + console.error('cash tracking session complete handler failed', error); + } + }, + ); +}; diff --git a/pos-background/tsconfig.json.liquid b/pos-background/tsconfig.json.liquid new file mode 100644 index 00000000..a13080d8 --- /dev/null +++ b/pos-background/tsconfig.json.liquid @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "ES2020", + "checkJs": true, + "allowJs": true, + "moduleResolution": "node", + "esModuleInterop": true, + "noEmit": true, + "skipLibCheck": true + }, + "include": ["./src", "./shopify.d.ts"] +} diff --git a/templates.json b/templates.json index 932f48ed..aa09a76d 100644 --- a/templates.json +++ b/templates.json @@ -1340,6 +1340,29 @@ ], "minimumCliVersion": "3.85.3" }, + { + "identifier": "pos_background", + "name": "POS background", + "defaultName": "pos-background", + "group": "UI extensions", + "supportLinks": [], + "url": "https://github.com/Shopify/extensions-templates", + "type": "ui_extension", + "extensionPoints": [], + "supportedFlavors": [ + { + "name": "TypeScript", + "value": "typescript", + "path": "pos-background" + }, + { + "name": "JavaScript", + "value": "vanilla-js", + "path": "pos-background" + } + ], + "minimumCliVersion": "3.85.3" + }, { "identifier": "cart_checkout_validation", "name": "Cart and checkout validation", From 5945bcaad2b92c05c71b12471c3a9cba077a0518 Mon Sep 17 00:00:00 2001 From: Monorail CI check running in Buildkite Date: Tue, 30 Jun 2026 18:23:16 -0700 Subject: [PATCH 2/2] Wrap listener registration in a single try/catch Assisted-By: devx/ad8a9826-c8c5-4579-8ce6-44cd1b431ab4 --- .../src/background-extension.liquid | 48 ++++++++----------- 1 file changed, 19 insertions(+), 29 deletions(-) diff --git a/pos-background/src/background-extension.liquid b/pos-background/src/background-extension.liquid index 733058c5..8a28df7e 100644 --- a/pos-background/src/background-extension.liquid +++ b/pos-background/src/background-extension.liquid @@ -9,38 +9,28 @@ import type { Api } from '@shopify/ui-extensions/pos.app.ready.data'; {% endif %} export default ({% if flavor contains "typescript" %}api: Api{% else %}_api{% endif %}) => { - console.log('background extension started'); - - shopify.addEventListener( - POS_EVENT_NAMES.TRANSACTION_COMPLETE, - (event{% if flavor contains "typescript" %}: TransactionCompleteEvent{% endif %}) => { - try { + try { + shopify.addEventListener( + POS_EVENT_NAMES.TRANSACTION_COMPLETE, + (event{% if flavor contains "typescript" %}: TransactionCompleteEvent{% endif %}) => { console.log('transaction complete', event); - } catch (error) { - console.error('transaction complete handler failed', error); - } - }, - ); + }, + ); - shopify.addEventListener( - POS_EVENT_NAMES.CASH_TRACKING_SESSION_START, - (event{% if flavor contains "typescript" %}: CashTrackingSessionStartEvent{% endif %}) => { - try { + shopify.addEventListener( + POS_EVENT_NAMES.CASH_TRACKING_SESSION_START, + (event{% if flavor contains "typescript" %}: CashTrackingSessionStartEvent{% endif %}) => { console.log('cash tracking session start', event); - } catch (error) { - console.error('cash tracking session start handler failed', error); - } - }, - ); + }, + ); - shopify.addEventListener( - POS_EVENT_NAMES.CASH_TRACKING_SESSION_COMPLETE, - (event{% if flavor contains "typescript" %}: CashTrackingSessionCompleteEvent{% endif %}) => { - try { + shopify.addEventListener( + POS_EVENT_NAMES.CASH_TRACKING_SESSION_COMPLETE, + (event{% if flavor contains "typescript" %}: CashTrackingSessionCompleteEvent{% endif %}) => { console.log('cash tracking session complete', event); - } catch (error) { - console.error('cash tracking session complete handler failed', error); - } - }, - ); + }, + ); + } catch (error) { + console.error('failed to register background extension listeners', error); + } };