Build a discount experience
In this tutorial, you'll use Shopify CLI to add a product discount extension to an existing app and add a page to your app so that merchants can create a discount in the Shopify admin. Shopify CLI generates starter code for building your app and extensions and automates many common development tasks.
You want to create a new discount type called "Volume discount" that offers a percentage off when customers purchase more than the minimum quantity of each product.
What you'll learn
Anchor link to section titled "What you'll learn"In this tutorial, you'll learn how to do the following tasks:
- Install the discount React library to your app
- Create a new page in your app where merchants can create a discount
- Generate a new product discount extension with boilerplate code
- Modify the Shopify Function code to generate the discounts at checkout
- Configure your extension
- Test the new discount in your development store
- Share a test error report and access it
Requirements
Anchor link to section titled "Requirements"You need to install Rust.
On Windows, Rust requires the Microsoft C++ Build Tools. Make sure to select the Desktop development with C++ workload when installing the tools.
You need to install cargo-wasi:
If you're not using the discount sample app, then you need to create an app that uses Shopify CLI 3.0 or higher, or migrate your existing app so that it's compatible with Shopify CLI 3.0 or higher.
Sample code
Anchor link to section titled "Sample code"If you want to quickly get started, then you can get the sample code by completing the following steps. This tutorial describes the sample code step by step.
Clone the discount sample app:
Deploy the function:
In
web/frontend/pages/Volume/new.jsx
, update theFUNCTION_ID
value with theSHOPIFY_VOLUME_ID
value in the app's.env
file.Start a local server for your app:
Proceed to creating and testing a discount.
Step 1: Install and configure the discount React library
Anchor link to section titled "Step 1: Install and configure the discount React library"The discount React library provides a set of React components for building a discount form page. The discount React library helps you replicate the experience and behavior of existing discount types in your own app.
Navigate to the
web/frontend
directory.Install the discount React library.
In the
web/frontend/components/providers
folder, create aDiscountProvider.jsx
file and add aDiscountProvider
component.In
web/frontend/components/providers/index.js
, exportDiscountProvider
.In
web/frontend/App.jsx
, import and renderDiscountProvider
and updatenavigationLinks
.Your
App.jsx
should look similar to the following example:
Step 2: Add a discount create page
Anchor link to section titled "Step 2: Add a discount create page"To create the Volume discount type, you'll replicate the existing discount page in the Shopify admin, and then you'll add a card where merchants can configure the Volume discount.
In the
web/frontend/pages
folder, create aVolume
folder.You'll add the discount create page to this folder.
Navigate to the
web/frontend
directory.Install
@shopify/react-form
to make managing your forms easier and@shopify/react-i18n
for localization support.In
web/index.js
, define the mutations you'll need to create discounts before theconst app = express()
line:Still in
web/index.js
, add the endpoints to create discounts directly afterapp.use(express.json())
:In the
web/frontend/pages/Volume
folder, create anew.jsx
file.This automatically creates a new URL (
Volume/new
) for your app based on the folder and file name.Do one of the following to navigate to your discount create page.
- Click the New volume discount navigation link in your app
- Add
/Volume/new
to the end of your app URL within the Shopify admin
You should have a sample discount page appear that's similar to Shopify's discount page.
Step 3: Add a card for the Volume discount configuration
Anchor link to section titled "Step 3: Add a card for the Volume discount configuration"In
web/frontend/pages/Volume/new.jsx
, populate thequantity
andpercentage
configuration properties and define initial states in your form state.In
web/frontend/pages/Volume/new.jsx
, parse thequantity
andpercentage
configuration properties and add them to your discount configuration.You can store your configuration in one or more metafields on a discount. Learn more about using metafields with input queries.
The following example stores configuration in a JSON metafield. Be sure to update the
METAFIELD_NAMESPACE
andMETAFIELD_CONFIGURATION_KEY
with your own namespace and key.In
web/frontend/pages/Volume/new.jsx
, after theMethodCard
component, add aCard
component for the Volume discount configuration.
Step 4: Add and deploy a product discount extension
Anchor link to section titled "Step 4: Add and deploy a product discount extension"Now that you have a discount create page in your app, you need to create the Shopify Function that will generate discounts during checkout. For this Volume discount type, you'll look at each variant in the cart, and if the customer has more products than the minimum quantity, then you return a percentage discount for those products.
Navigate to your app directory.
Run one of the following commands to create a new product discount extension:
Set your extension name to
Volume
, and choose theRust
language option.Navigate to
extensions/Volume
.Build the function's Wasm module.
If you encounter any errors, ensure that you've installed Rust and cargo-wasi.
Copy the following code into
input.graphql
.input.graphql
defines the input for the function. You need the items in the cart, the quantity, the variant, and the configuration stored in a metafield.Replace
YOUR_NAMESPACE
with your app name ininput.graphql
and inweb/frontend/pages/Volume/new.jsx
. For example,discounts-plus
.In
src/api.rs
, update the following areas:- The configuration structure in
pub struct Configuration
- The structs representing the input query defined in the previous step
Types for serializing the input and output of your function are located in
src/api.rs
and written in Rust.You can replace the
src/api.rs
file with the following code:- The configuration structure in
Your main discounting logic is located in
src/main.rs
and written in Rust. Insrc/main.rs
, update the following areas:- The
function()
method - The corresponding test suite
You can replace the
src/main.rs
file with the following code:- The
In
shopify.function.extension.toml
, edit theui.paths
to connect the function to your frontend code.This code will tell Shopify which paths in your app to open when a merchant creates or updates a
Volume
discount.Deploy your app along with the function.
In
web/frontend/pages/Volume/new.jsx
, update theFUNCTION_ID
value with theSHOPIFY_VOLUME_ID
value in the app's.env
file.This will associate the discount that you create with the backend function logic to execute when a discount is created.
Step 5: Request the write_discounts
access scope
Anchor link to section titled "Step 5: Request the write_discounts access scope"Your app must request the write_discounts
access scope to create discounts.
In
shopify.app.toml
, add thewrite_discounts
access scope.Restart the server and reload the app:
You should be prompted to accept the new access scope permissions in your store.
Step 6: Create and test a discount in your store
Anchor link to section titled "Step 6: Create and test a discount in your store"- From your Shopify admin, go to Discounts.
- Click the Create discount button.
- Click the Volume discount type you created under your app name. You should see the create page for your Volume discount.
- Fill in values for the discount, including minimum quantity and percentage discount.
- Click Save.
Navigate to Discounts.
You should see a new discount.
Navigate to your online store and add multiple items to your cart.
Go to checkout.
You should see a Volume discount that's applied based on your configuration.
Troubleshooting
Anchor link to section titled "Troubleshooting"When the merchant shares an error report from the Shopify admin, you can access it from the app's Extensions section in your Partner Dashboard.
This section describes how to share a test error report and access it.
Share a test error report
Anchor link to section titled "Share a test error report"When a function is executed and an error occurs, a banner displays in the Discounts page of the Shopify admin. The banner contains information about when errors started occurring. It also includes a link that merchants can use to share information with developers about function runs that failed.
- From your Shopify admin, go to Discounts.
- Click the error banner.
- Click Share the error reports with
<developer-name>
. - Select whether the error report includes the last 10 times the customization ran on checkout.
- Click Share.
You'll receive an email notification.
Access the error report
Anchor link to section titled "Access the error report"- From your Partner Dashboard, go to Apps.
- Click the app that you deployed your function to.
- Click Extensions.
- Click the name of your function.
In the Total errors box, click Error runs.
All of the function runs that failed display in a list.
From the list, click the failed function run that you shared.
You can view the error report.
For information on inspecting error details, refer to Debugging.