-
Notifications
You must be signed in to change notification settings - Fork 0
Add POS UI Extensions tutorial code examples #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| # Environment Configuration | ||
| .env | ||
| .env.* | ||
|
|
||
| # Dependency directory | ||
| node_modules | ||
|
|
||
| # Test coverage directory | ||
| coverage | ||
|
|
||
| # Ignore Apple macOS Desktop Services Store | ||
| .DS_Store | ||
|
|
||
| # Logs | ||
| logs | ||
| *.log | ||
|
|
||
| # extensions build output | ||
| extensions/*/build | ||
| extensions/*/dist | ||
|
|
||
| # lock files | ||
|
|
||
|
|
||
|
|
||
|
|
||
| # Ignore shopify files created during app dev | ||
| .shopify/* | ||
| .shopify.lock |
30 changes: 30 additions & 0 deletions
30
example-pos-ui-extensions--discounts--preact/.graphqlrc.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| const fs = require("node:fs"); | ||
|
|
||
| function getConfig() { | ||
| const config = { | ||
| projects: {}, | ||
| }; | ||
|
|
||
| let extensions = []; | ||
| try { | ||
| extensions = fs.readdirSync("./extensions"); | ||
| } catch { | ||
| // ignore if no extensions | ||
| } | ||
|
|
||
| for (const entry of extensions) { | ||
| const extensionPath = `./extensions/${entry}`; | ||
| const schema = `${extensionPath}/schema.graphql`; | ||
| if (!fs.existsSync(schema)) { | ||
| continue; | ||
| } | ||
| config.projects[entry] = { | ||
| schema, | ||
| documents: [`${extensionPath}/**/*.graphql`], | ||
| }; | ||
| } | ||
|
|
||
| return config; | ||
| } | ||
|
|
||
| module.exports = getConfig(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| engine-strict=true | ||
| auto-install-peers=true | ||
| shamefully-hoist=true | ||
| @shopify:registry=https://registry.npmjs.org |
5 changes: 5 additions & 0 deletions
5
example-pos-ui-extensions--discounts--preact/.vscode/extensions.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| { | ||
| "recommendations": [ | ||
| "graphql.vscode-graphql" | ||
| ] | ||
| } |
8 changes: 8 additions & 0 deletions
8
example-pos-ui-extensions--discounts--preact/.vscode/mcp.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| { | ||
| "servers": { | ||
| "shopify-dev-mcp": { | ||
| "command": "npx", | ||
| "args": ["-y", "@shopify/dev-mcp@latest"] | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,78 @@ | ||
| # Shopify App Template - Extension only | ||
|
|
||
| This is a template for building an [extension-only Shopify app](https://shopify.dev/docs/apps/build/app-extensions/build-extension-only-app). It contains the basics for building a Shopify app that uses only app extensions. | ||
|
|
||
| This template doesn't include a server or the ability to embed a page in the Shopify Admin. If you want either of these capabilities, choose the [Remix app template](https://github.com/Shopify/shopify-app-template-remix) instead. | ||
|
|
||
| Whether you choose to use this template or another one, you can use your preferred package manager and the Shopify CLI with [these steps](#installing-the-template). | ||
|
|
||
| ## Benefits | ||
|
|
||
| Shopify apps are built on a variety of Shopify tools to create a great merchant experience. The [create an app](https://shopify.dev/docs/apps/getting-started/create) tutorial in our developer documentation will guide you through creating a Shopify app. | ||
|
|
||
| This app template does little more than install the CLI and scaffold a repository. | ||
|
|
||
| ## Getting started | ||
|
|
||
| ### Requirements | ||
|
|
||
| 1. You must [download and install Node.js](https://nodejs.org/en/download/) if you don't already have it. | ||
| 1. You must [create a Shopify partner account](https://partners.shopify.com/signup) if you don’t have one. | ||
| 1. You must create a store for testing if you don't have one, either a [development store](https://help.shopify.com/en/partners/dashboard/development-stores#create-a-development-store) or a [Shopify Plus sandbox store](https://help.shopify.com/en/partners/dashboard/managing-stores/plus-sandbox-store). | ||
|
|
||
| ### Installing the template | ||
|
|
||
| This template can be installed using your preferred package manager: | ||
|
|
||
| Using yarn: | ||
|
|
||
| ```shell | ||
| yarn create @shopify/app | ||
| ``` | ||
|
|
||
| Using npm: | ||
|
|
||
| ```shell | ||
| npm init @shopify/app@latest | ||
| ``` | ||
|
|
||
| Using pnpm: | ||
|
|
||
| ```shell | ||
| pnpm create @shopify/app@latest | ||
| ``` | ||
|
|
||
| This will clone the template and install the required dependencies. | ||
|
|
||
| #### Local Development | ||
|
|
||
| [The Shopify CLI](https://shopify.dev/docs/apps/tools/cli) connects to an app in your Partners dashboard. It provides environment variables and runs commands in parallel. | ||
|
|
||
| You can develop locally using your preferred package manager. Run one of the following commands from the root of your app. | ||
|
|
||
| Using yarn: | ||
|
|
||
| ```shell | ||
| yarn dev | ||
| ``` | ||
|
|
||
| Using npm: | ||
|
|
||
| ```shell | ||
| npm run dev | ||
| ``` | ||
|
|
||
| Using pnpm: | ||
|
|
||
| ```shell | ||
| pnpm run dev | ||
| ``` | ||
|
|
||
| Open the URL generated in your console. Once you grant permission to the app, you can start development (such as generating extensions). | ||
|
|
||
| ## Developer resources | ||
|
|
||
| - [Introduction to Shopify apps](https://shopify.dev/docs/apps/getting-started) | ||
| - [App extensions](https://shopify.dev/docs/apps/build/app-extensions) | ||
| - [Extension only apps](https://shopify.dev/docs/apps/build/app-extensions/build-extension-only-app) | ||
| - [Shopify CLI](https://shopify.dev/docs/apps/tools/cli) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| # Security Policy | ||
|
|
||
| ## Supported versions | ||
|
|
||
| ### New features | ||
|
|
||
| New features will only be added to the master branch and will not be made available in point releases. | ||
|
|
||
| ### Bug fixes | ||
|
|
||
| Only the latest release series will receive bug fixes. When enough bugs are fixed and its deemed worthy to release a new gem, this is the branch it happens from. | ||
|
|
||
| ### Security issues | ||
|
|
||
| Only the latest release series will receive patches and new versions in case of a security issue. | ||
|
|
||
| ### Severe security issues | ||
|
|
||
| For severe security issues we will provide new versions as above, and also the last major release series will receive patches and new versions. The classification of the security issue is judged by the core team. | ||
|
|
||
| ### Unsupported Release Series | ||
|
|
||
| When a release series is no longer supported, it's your own responsibility to deal with bugs and security issues. If you are not comfortable maintaining your own versions, you should upgrade to a supported version. | ||
|
|
||
| ## Reporting a bug | ||
|
|
||
| All security bugs in shopify repositories should be reported to [our hackerone program](https://hackerone.com/shopify) | ||
| Shopify's whitehat program is our way to reward security researchers for finding serious security vulnerabilities in the In Scope properties listed at the bottom of this page, including our core application (all functionality associated with a Shopify store, particularly your-store.myshopify.com/admin) and certain ancillary applications. | ||
|
|
||
| ## Disclosure Policy | ||
|
|
||
| We look forward to working with all security researchers and strive to be respectful, always assume the best and treat others as peers. We expect the same in return from all participants. To achieve this, our team strives to: | ||
|
|
||
| - Reply to all reports within one business day and triage within two business days (if applicable) | ||
| - Be as transparent as possible, answering all inquires about our report decisions and adding hackers to duplicate HackerOne reports | ||
| - Award bounties within a week of resolution (excluding extenuating circumstances) | ||
| - Only close reports as N/A when the issue reported is included in Known Issues, Ineligible Vulnerabilities Types or lacks evidence of a vulnerability | ||
|
|
||
| **The following rules must be followed in order for any rewards to be paid:** | ||
|
|
||
| - You may only test against shops you have created which include your HackerOne YOURHANDLE @ wearehackerone.com registered email address. | ||
| - You must not attempt to gain access to, or interact with, any shops other than those created by you. | ||
| - The use of commercial scanners is prohibited (e.g., Nessus). | ||
| - Rules for reporting must be followed. | ||
| - Do not disclose any issues publicly before they have been resolved. | ||
| - Shopify reserves the right to modify the rules for this program or deem any submissions invalid at any time. Shopify may cancel the whitehat program without notice at any time. | ||
| - Contacting Shopify Support over chat, email or phone about your HackerOne report is not allowed. We may disqualify you from receiving a reward, or from participating in the program altogether. | ||
| - You are not an employee of Shopify; employees should report bugs to the internal bug bounty program. | ||
| - You hereby represent, warrant and covenant that any content you submit to Shopify is an original work of authorship and that you are legally entitled to grant the rights and privileges conveyed by these terms. You further represent, warrant and covenant that the consent of no other person or entity is or will be necessary for Shopify to use the submitted content. | ||
| - By submitting content to Shopify, you irrevocably waive all moral rights which you may have in the content. | ||
| - All content submitted by you to Shopify under this program is licensed under the MIT License. | ||
| - You must report any discovered vulnerability to Shopify as soon as you have validated the vulnerability. | ||
| - Failure to follow any of the foregoing rules will disqualify you from participating in this program. | ||
|
|
||
| \*\* Please see our [Hackerone Profile](https://hackerone.com/shopify) for full details | ||
|
|
||
| ## Receiving Security Updates | ||
|
|
||
| To receive all general updates to vulnerabilities, please subscribe to our hackerone [Hacktivity](https://hackerone.com/shopify/hacktivity) |
Empty file.
10 changes: 10 additions & 0 deletions
10
example-pos-ui-extensions--discounts--preact/extensions/discount/package.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| { | ||
| "name": "discount", | ||
| "private": true, | ||
| "version": "1.0.0", | ||
| "license": "UNLICENSED", | ||
| "dependencies": { | ||
| "@shopify/ui-extensions": "2025.10.x", | ||
| "preact": "^10.10.x" | ||
| } | ||
| } |
13 changes: 13 additions & 0 deletions
13
example-pos-ui-extensions--discounts--preact/extensions/discount/shopify.d.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| import '@shopify/ui-extensions'; | ||
|
|
||
| //@ts-ignore | ||
| declare module './src/Tile.jsx' { | ||
| const shopify: import('@shopify/ui-extensions/pos.home.tile.render').Api; | ||
| const globalThis: { shopify: typeof shopify }; | ||
| } | ||
|
|
||
| //@ts-ignore | ||
| declare module './src/Modal.jsx' { | ||
| const shopify: import('@shopify/ui-extensions/pos.home.modal.render').Api; | ||
| const globalThis: { shopify: typeof shopify }; | ||
| } |
18 changes: 18 additions & 0 deletions
18
example-pos-ui-extensions--discounts--preact/extensions/discount/shopify.extension.toml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| api_version = "2025-10" | ||
|
|
||
| [[extensions]] | ||
| type = "ui_extension" | ||
| name = "Discount" | ||
| uid = "bdff5acd-d192-ddcd-05cf-ad6d759e978ac7c62980" | ||
| handle = "discount" | ||
| description = "Add discount" | ||
|
|
||
| # module: file that contains your extension’s source code | ||
| # target: location where your extension appears in POS | ||
| [[extensions.targeting]] | ||
| module = "./src/Tile.jsx" | ||
| target = "pos.home.tile.render" | ||
|
|
||
| [[extensions.targeting]] | ||
| module = "./src/Modal.jsx" | ||
| target = "pos.home.modal.render" |
26 changes: 26 additions & 0 deletions
26
example-pos-ui-extensions--discounts--preact/extensions/discount/src/Modal.jsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| import { render } from "preact"; | ||
|
|
||
| export default async () => { | ||
| render(<Extension />, document.body); | ||
| }; | ||
|
|
||
| function Extension() { | ||
| // [START modal.define-onpress] | ||
| const onButtonClick = (type, title, amount) => { | ||
| shopify.cart.applyCartDiscount(type, title, amount); | ||
| shopify.toast.show("Discount applied"); | ||
| }; | ||
| // [END modal.define-onpress] | ||
| return ( | ||
| <s-page heading="Available Discounts"> | ||
| <s-scroll-box padding="base"> | ||
| <s-button onClick={() => onButtonClick("Percentage", "25% off", "25")}> | ||
| 25% | ||
| </s-button> | ||
| <s-button onClick={() => onButtonClick("FixedAmount", "$10 off", "10")}> | ||
| $10 | ||
| </s-button> | ||
| </s-scroll-box> | ||
| </s-page> | ||
| ); | ||
| } |
36 changes: 36 additions & 0 deletions
36
example-pos-ui-extensions--discounts--preact/extensions/discount/src/Tile.jsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| import {render} from 'preact'; | ||
| import {useState, useEffect} from 'preact/hooks'; | ||
|
|
||
| export default async () => { | ||
| render(<Extension />, document.body); | ||
| } | ||
|
|
||
| function Extension() { | ||
| const shouldDisable = (subtotal) => { | ||
| return Number(subtotal) <= 100; | ||
| }; | ||
|
|
||
| // [START tile.enable] | ||
| const [disabled, setDisabled] = useState( | ||
| shouldDisable(shopify.cart.current.value.subtotal), | ||
| ); | ||
| // [END tile.enable] | ||
|
|
||
| // [START tile.subscribe] | ||
| useEffect(() => { | ||
| const unsubscribe = shopify.cart.current.subscribe((cart) => { | ||
| setDisabled(shouldDisable(cart.subtotal)); | ||
| }); | ||
| return unsubscribe; | ||
| }, []); | ||
| // [END tile.subscribe] | ||
|
|
||
| return ( | ||
| <s-tile | ||
| heading="Discount Example App" | ||
| subheading="Preact" | ||
| onClick={() => shopify.action.presentModal()} | ||
| disabled={disabled} | ||
| /> | ||
| ); | ||
| } |
12 changes: 12 additions & 0 deletions
12
example-pos-ui-extensions--discounts--preact/extensions/discount/tsconfig.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| { | ||
| "compilerOptions": { | ||
| "jsx": "react-jsx", | ||
| "jsxImportSource": "preact", | ||
| "target": "ES2020", | ||
| "checkJs": true, | ||
| "allowJs": true, | ||
| "moduleResolution": "node", | ||
| "esModuleInterop": true, | ||
| "noEmit": true | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.