> Portal Navigation: > > - Append `.md` to any URL under `https://dev.wix.com/docs/` to get its markdown version. > - Pages are either content pages (article or reference text) or menu pages (a list of links to child pages). > - To get a menu page, truncate any URL to a parent path and append `.md` (e.g. `https://dev.wix.com/docs/sdk.md`, `https://dev.wix.com/docs/sdk/core-modules.md`). > - Top-level index of all portals: https://dev.wix.com/docs/llms.txt > - Full concatenated docs: https://dev.wix.com/docs/llms-full.txt ## Resource: Tutorial | Create a Site Plugin for the Wix Stores Product Page with the CLI ## Article: Tutorial | Create a Site Plugin for the Wix Stores Product Page with the CLI ## Article Link: https://dev.wix.com/docs/build-apps/get-started/tutorials/tutorial-create-a-site-plugin-for-the-wix-stores-product-page-with-the-cli.md ## Article Content: # Tutorial | Create a Site Plugin for the Wix Stores Product Page with the CLI In this tutorial, you'll create a digital sale banner [site plugin](https://dev.wix.com/docs/build-apps/develop-your-app/extensions/site-extensions/site-plugins/about-site-plugin-extensions.md) for the Wix Stores product page using the [CLI](https://dev.wix.com/docs/wix-cli/guides/about-the-wix-cli.md). This plugin displays a small banner on digital products to let customers know this product is part of the digital sale promotion. The plugin appears in a Wix Stores [product page slot](https://dev.wix.com/docs/build-apps/develop-your-app/extensions/site-extensions/site-plugins/supported-wix-app-pages/wix-stores/wix-stores-product-page.md#plugin-slots). Follow these steps to build the product page site plugin: 1. Create an app with the CLI. 2. Add a site plugin extension. 3. Code your plugin. 4. Test your plugin. 5. Build and deploy your app. > **Note:** Slots differ slightly depending on [which version of Wix Stores](https://support.wix.com/en/article/wix-stores-customizing-your-product-page) a user has on their site. This tutorial works for both versions. Learn more about building [product page site plugins](https://dev.wix.com/docs/build-apps/develop-your-app/extensions/site-extensions/site-plugins/supported-wix-app-pages/wix-stores/wix-stores-product-page.md). ## Step 1 | Create an app with the CLI Create a new app project using the CLI. For detailed instructions, see [Quick Start an App](https://dev.wix.com/docs/wix-cli/guides/get-started/quick-start-an-app.md). ## Step 2 | Add a site plugin extension [Add a site plugin extension](https://dev.wix.com/docs/wix-cli/guides/extensions/site-extensions/site-plugins/add-a-site-plugin-extension.md) to your app that renders on a Wix Stores product page. To add a site plugin extension, follow these steps: 1. Run the following command: ```bash npm run generate ``` 2. When prompted, make sure to select the following: - `Site Plugin` as the extension. - `Wix Stores` as the Wix app. - `product-page-details-2` as the slot under `New product page`. 3. Open your plugin's `extension.ts` file and add support for the [old product page](https://dev.wix.com/docs/build-apps/develop-your-app/extensions/site-extensions/site-plugins/supported-wix-app-pages/wix-stores/wix-stores-product-page.md) slot so your plugin works with both versions of Wix Stores. The old product page uses the same `slotId` but has different `appDefinitionId` and `widgetId` values. Add the following placement to the `placements` array: ```tsx placements: [ { //New product page appDefinitionId: "a0c68605-c2e7-4c8d-9ea1-767f9770e087", widgetId: "6a25b678-53ec-4b37-a190-65fcd1ca1a63", slotId: "product-page-details-2" }, { //Old product page appDefinitionId: "1380b703-ce81-ff05-f115-39571d94dfcd", widgetId: "13a94f09-2766-3c40-4a32-8edb5acdd8bc", slotId: "product-page-details-2" } ] ``` ## Step 3 | Code your plugin Add code to check if a product is digital and then display a sale banner on digital products. If it's not a digital product, don't display any banner.
**Important:** You must support both [Stores V1 APIs](https://dev.wix.com/docs/api-reference/business-solutions/stores/catalog-v1/catalog/get-product.md) and [Stores V3 APIs](https://dev.wix.com/docs/api-reference/business-solutions/stores/catalog-v3/products-v3/get-product.md) because different sites may have different API versions available. Your plugin should try both APIs and use whichever one works.To code your plugin: 1. Open `src/site/plugins/custom-elements/digital-sale-banner/plugin.tsx`. 2. Delete the existing code in the file. 3. Paste the following import statements at the beginning of your file: > **Note:** Import both [Products V1 API](https://dev.wix.com/docs/api-reference/business-solutions/stores/catalog-v1/catalog/get-product.md) and [Products V3 API](https://dev.wix.com/docs/api-reference/business-solutions/stores/catalog-v3/products-v3/get-product.md). ```tsx import { products, productsV3 } from '@wix/stores'; ``` 4. Create the custom element class. Define the class that extends `HTMLElement` and set up the observed attributes: ```tsx class SaleBanner extends HTMLElement { static get observedAttributes() { return ['display-name', 'product-id']; } connectedCallback() { this.checkProductAndRender(); } attributeChangedCallback() { this.checkProductAndRender(); } ``` 5. Add the method that checks if the product is digital. This method tries both the [Products V1 API](https://dev.wix.com/docs/api-reference/business-solutions/stores/catalog-v1/catalog/get-product.md) and [Products V3 API](https://dev.wix.com/docs/api-reference/business-solutions/stores/catalog-v3/products-v3/get-product.md) and uses whichever one works: ```tsx async checkProductAndRender() { const productId = this.getAttribute('product-id'); if (!productId) { this.innerHTML = ''; return; } let isDigital = false; let foundProduct = false; // Try V1 API try { const response = await products.getProduct(productId); if (response.product) { foundProduct = true; if (response.product.productType === 'digital') { isDigital = true; } } } catch (error) { // V1 API failed, will try V3 } // If V1 didn't work, try V3 API if (!foundProduct) { try { const response = await productsV3.getProduct(productId); if (response) { foundProduct = true; if (response.productType === 'DIGITAL') { isDigital = true; } } } catch (error) { // Both APIs failed } } // Only show banner for digital products if (isDigital) { this.render(); } else { this.innerHTML = ''; } } ``` 6. Add the render method that displays the banner on the site: ```tsx render() { const customText = this.getAttribute('display-name'); const displayText = customText || 'Digital Sale'; this.innerHTML = `