Getting started with client-side validation in checkout
You want to add a validation at checkout that blocks customers from progressing in the checkout when they input invalid data.
In this tutorial, you'll use the Checkout::Contact::RenderAfter
extension point and checkout UI components to collect input, and validate it. Using the buyerJourney
intercept and block_progress
capabilities, you'll block the customer from progressing in checkout and show a validation error. You'll also adjust your extension UI to handle cases where the merchant doesn't allow the extension to block the checkout progress.
This tutorial is for validating the customer's age, but you can use it as the basis for building other use cases for field validation, such as address or tax code validation.
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:
Create a checkout UI extension that renders some text in the checkout flow.
Run the extension locally and test it on a development store.
Set up the extension point and capabilities.
Render a
TextField
and set the props that you'll need to implement validation.Use the
buyerJourney
intercept to perform validation, block progress, and pass an error to the checkout UI.Check whether you have the ability to block checkout progress.
Deploy your extension code to Shopify.
Requirements
Anchor link to section titled "Requirements"You've created a Partner account.
You've created a new development store, where you've enabled the checkout extensibility developer preview.
You've created an app that uses Shopify CLI 3.0 or higher, or you've migrated your existing app so that it's compatible with Shopify CLI 3.0 or higher.
Sample code
Anchor link to section titled "Sample code"Using the Checkout::Contact::RenderAfter
extension point, the sample code imports the TextField
component to build the UI. It uses the buyerJourney
intercept to validate the input, block checkout progress, and return validation errors to the checkout UI.
It detects whether the extension has the block_progress
capability. If it doesn't, then it updates the label
and required
props for the TextField
accordingly.
You can copy and paste the following code into your index
file and add a few example values to get the extension to render in the browser.
You'll also need to update your extension's configuration file with the information in the code example.
The rest of the tutorial walks through this sample code step-by-step.
Step 1: Create a UI extension
Anchor link to section titled "Step 1: Create a UI extension"To create a checkout UI extension, you can use Shopify CLI, which generates starter code for building your extension and automates common development tasks.
Navigate to your app directory:
Run one of the following commands to create a new checkout UI extension:
Select a language for your extension. You can choose from TypeScript, JavaScript, TypeScript React, or JavaScript React.
You should now have a new extension directory in your app's directory. The extension directory includes the extension script at
src/index.{file-extension}
. The following is an example directory structure:Start your development server to build and preview your app:
To learn about the processes that are executed when you run
dev
, refer to the Shopify CLI command reference.Press
p
to open the developer console. In the developer console page, click on the preview link for your extension.
Step 2: Import components
Anchor link to section titled "Step 2: Import components"In the index
file, import the components from the Checkout UI extensions API that you need to build the extension:
Step 3: Set up the extension point and capability
Anchor link to section titled "Step 3: Set up the extension point and capability"The Checkout::Contact::RenderAfter
extension point renders the extension after the contact section on the information step of the checkout. The block_progress
capability enables the extension to block checkout progress if the merchant allows it when configuring the extension within the checkout editor.
Set the entry point for the extension in
index
:Set the extension point and
block_progress
capability in the shopify.ui.extension.toml file:
Step 4: Render the custom field
Anchor link to section titled "Step 4: Render the custom field"In this step, you'll render a text field to gather the customer's age. The TextField
component is used to add a required field.
Step 5: Perform validation
Anchor link to section titled "Step 5: Perform validation"In this step, you'll use the buyerJourney
intercept to show an error message in the checkout UI and block checkout progress when the customer inputs an invalid age.
Step 6: Check for the ability to block checkout progress
Anchor link to section titled "Step 6: Check for the ability to block checkout progress"Adding the block_progress
capability to your shopify.ui.extension.toml
file doesn't guarantee that the extension can block checkout progress. The merchant can allow or disallow this capability in the checkout editor. We recommend adjusting the extension accordingly to handle cases where merchants don't grant the extension this capability.
The following code snippet from where you rendered the extension components detects whether the merchant has granted the ability to block checkout progress. If you're collecting optional input, then you should update the label and whether the field is required:
Step 7: Deploy the UI extension
Anchor link to section titled "Step 7: Deploy the UI extension"When you're ready, you can deploy your extension code to Shopify.
Navigate to your app directory.
Run one of the following commands:
To learn about the processes that are executed when you run
deploy
, refer to the Shopify CLI command reference.
Troubleshooting
Anchor link to section titled "Troubleshooting"This section describes how to solve some potential errors when you run dev
for an app that contains a checkout UI extension.
Property token error
Anchor link to section titled "Property token error"If you receive the error ShopifyCLI:AdminAPI requires the property token to be set
, then you'll need to use the --checkout-cart-url
flag to direct the CLI to open a checkout session for you.
Missing checkout link
Anchor link to section titled "Missing checkout link"If you don't receive the test checkout URL when you run dev
, then verify the following:
You have a development store populated with products.
You're logged in to the correct Partners organization and development store. To verify, check your app info using the following command:
Otherwise, you can manually create a checkout with the following steps:
From your development store's storefront, add some products to your cart.
From the cart, click Checkout.
From directory of the app that contains your extension, run
dev
to preview your app:On the checkout page for your store, change the URL by appending the
?dev=https://{tunnel_url}/extensions
query string and reload the page. Thetunnel_url
parameter allows your app to be accessed using a unique HTTPS URL.You should now see a rendered order note that corresponds to the code in your project template.
- Learn about the components that are available in checkout UI extensions.
Consult the API reference for checkout UI extension points and their respective types.
Learn how to release and publish a version of your checkout UI extension.