import Deploy from 'app/views/partials/extensions/deploy.mdx'
import CheckoutUiRequirements from 'app/views/partials/apps/checkout/ui-extensions/requirements.mdx'
import CheckoutUiCreate from 'app/views/partials/apps/checkout/ui-extensions/create.mdx'
import CheckoutUiPreview from 'app/views/partials/apps/checkout/ui-extensions/preview.mdx'
import CheckoutUiReference from 'app/views/partials/apps/checkout/ui-extensions/reference.mdx'
<Overview>
A custom field is a property that allows users to enter text into a user interface. For example, you might want to create a custom field that collects delivery instructions from customers.
In this tutorial, you'll use checkout UI extensions to create a custom field for collecting delivery instructions from customers, and then save those instructions to a metafield.
This tutorial is for delivery instructions, but you can use it as an example to build other use cases for custom fields.
Follow along with this tutorial to build a sample app, or clone the completed sample app.
Before you start, consider reviewing our [custom field checkout UI extension UX guidelines](/docs/apps/build/checkout/fields-banners/ux-for-fields).
<Notice type="shopifyPlus" title="Shopify Plus">
Checkout UI extensions are available only to [Shopify Plus](https://www.shopify.com/plus) merchants.
</Notice>
<video autoPlay muted loop controls>
<source src="/assets/apps/checkout/delivery-instructions.webm" type="video/webm"/>
<source src="/assets/apps/checkout/delivery-instructions.mp4" type="video/mp4"/>
</video>
## What you'll learn
In this tutorial, you'll learn how to do the following:
- Generate a checkout UI extension that appears in the checkout flow using Shopify CLI.
- Set up configurations for your Checkout UI extension in the extension TOML file.
- Use the Checkout UI component library to render an optional input field for customers to add a note.
- Save the note to a metafield and display the value in the Shopify admin.
</Overview>
<Repo
extension="javascript"
href="https://github.com/Shopify/example-checkout--custom-field--js"
/>
<Repo
extension="react"
href="https://github.com/Shopify/example-checkout--custom-field--react"
/>
<Picker name="extension">
<PickerOption name="react" />
<PickerOption name="javascript" />
</Picker>
<Requirements>
<CheckoutUiRequirements />
</Requirements>
<StepSection>
<Step>
## Create a Checkout UI extension
To create a checkout UI extension, you'll use Shopify CLI, which generates starter code for building your extension.
<Substep>
<CodeRef
extension="react"
href="https://github.com/Shopify/example-checkout--custom-field--react/blob/main/extensions/custom-field/shopify.extension.toml" />
<CodeRef
extension="javascript"
href="https://github.com/Shopify/example-checkout--custom-field--js/blob/main/extensions/custom-field/shopify.extension.toml" />
<CheckoutUiCreate />
</Substep>
</Step>
<Step>
### Set up an extension target
Set up a target for your checkout UI extension. [Targets](/docs/api/checkout-extensions/checkout#extension-targets) control where your extension renders in the checkout flow.
<Substep>
<CodeRef
extension="react"
href="https://github.com/Shopify/example-checkout--custom-field--react/blob/main/extensions/custom-field/src/Checkout.jsx" tag="custom-field.ext-index"/>
<CodeRef
extension="javascript"
href="https://github.com/Shopify/example-checkout--custom-field--js/blob/main/extensions/custom-field/src/Checkout.js" tag="custom-field.ext-index"/>
#### Export the target from your script file
In your <If extension="react">`Checkout.jsx`</If><If extension="javascript">`Checkout.js`</If> file, set the entrypoint for the checkout extension, and then export it so it can be referenced in your configuration.
Create <If extension="react">a `reactExtension`</If> <If extension="javascript"> an `extension`</If> function that references your target, and export it using the default export.
---
This extension uses the `purchase.checkout.shipping-option-list.render-after` target so the user can provide all shipping and delivery information at the same stage in the checkout process.
You can define more than one target so that merchants can add the extension to multiple locations in the checkout. You can do this by using multiple <If extension="react">`reactExtension`</If> <If extension="javascript">`extension`</If> functions with different [static targets](/docs/api/checkout-ui-extensions/latest/extension-targets-overview#static-extension-targets).
<Resources>
<If extension="react">
[reactExtension](/docs/api/checkout-ui-extensions#extension-targets)
</If>
<If extension="javascript">
[extension](/docs/api/checkout-ui-extensions#extension-targets)
</If>
[purchase.checkout.shipping-option-list.render-after](/docs/api/checkout-ui-extensions/latest/apis/extensiontargets#typesofextensiontargets-propertydetail-purchasecheckoutshippingoptionlistrenderafter)
</Resources>
</Substep>
<Substep>
<CodeRef
extension="react"
href="https://github.com/Shopify/example-checkout--custom-field--react/blob/main/extensions/custom-field/shopify.extension.toml" tag="custom-field.ext-config"/>
<CodeRef
extension="javascript"
href="https://github.com/Shopify/example-checkout--custom-field--js/blob/main/extensions/custom-field/shopify.extension.toml" tag="custom-field.ext-config"/>
<CheckoutUiReference />
</Substep>
</Step>
<Step>
## Set up a metafield
Now that you've set up the extension target, you'll save custom field values in a metafield. Regular metafields are available to any app or extension.
<Notice type="info">
If you need to capture multiple dynamic fields, then consider using [checkout attributes](/docs/api/checkout-ui-extensions/unstable/apis/attributes#checkoutapi-propertydetail-applyattributechange) where you can define a namespace and key programatically without having to pre-define them in your `shopify.extension.toml`. For example, you might need to collect input for [both one-time purchase and subscription delivery group lists](/docs/api/checkout-ui-extensions/unstable/targets/shipping/purchase-checkout-shipping-option-list-render-before).
</Notice>
<Substep>
### Define the metafield namespace and key
<CodeRef
extension="react"
href="https://github.com/Shopify/example-checkout--custom-field--react/blob/main/extensions/custom-field/src/Checkout.jsx" tag="custom-field.define-metafield"/>
<CodeRef
extension="javascript"
href="https://github.com/Shopify/example-checkout--custom-field--js/blob/main/extensions/custom-field/src/Checkout.js" tag="custom-field.define-metafield"/>
Set a namespace and key for the metafield where you want to store the custom field value.
Later, you'll expose values stored in this metafield to merchants in the Shopify admin.
---
A [metafield](/docs/apps/build/custom-data/metafields/manage-metafields) is a custom field that you can use to store additional information about a Shopify resource. You can use metafields to store information specific to your app without setting up your own storage.
</Substep>
</Step>
<Step>
## Add a delivery instruction input
Build a basic user interface using components from the [checkout UI extensions](/docs/api/checkout-ui-extensions/latest/components) component library.
<Substep>
### Add a delivery instruction option and text field
<CodeRef
extension="react"
href="https://github.com/Shopify/example-checkout--custom-field--react/blob/main/extensions/custom-field/src/Checkout.jsx" tag="custom-field.instruction-ui"/>
<CodeRef
extension="javascript"
href="https://github.com/Shopify/example-checkout--custom-field--js/blob/main/extensions/custom-field/src/Checkout.js" tag="custom-field.instruction-ui"/>
Using Checkout UI components, build a basic UI for the delivery instruction input.
---
This UI includes a checkbox to specify whether the customer wants to add a delivery instruction. When the checkbox is checked, a text field appears for the customer to enter the delivery instruction. If the customer has already entered a value, then the value is displayed.
Checkout UI extensions are limited to specific UI components exposed by the platform [for security reasons](/docs/api/checkout-ui-extensions#security). Checkout UI components allow you to create a UI that feels seamless within the checkout experience, and that inherits a merchant's brand settings.
<Resources>
[BlockStack](/docs/api/checkout-ui-extensions/latest/components/structure/blockstack)
[Checkbox](/docs/api/checkout-ui-extensions/latest/components/forms/checkbox)
[TextField](/docs/api/checkout-ui-extensions/latest/components/forms/textfield)
</Resources>
</Substep>
<Substep>
### Store the user input in the metafield
<CodeRef
extension="react"
href="https://github.com/Shopify/example-checkout--custom-field--react/blob/main/extensions/custom-field/src/Checkout.jsx" tag="custom-field.update-metafield"/>
<CodeRef
extension="javascript"
href="https://github.com/Shopify/example-checkout--custom-field--js/blob/main/extensions/custom-field/src/Checkout.js" tag="custom-field.store-value"/>
<If extension="react">
Use the `useApplyMetafieldsChange` hook to store the value that the customer enters in the `metafields` property of the checkout. This metafield value is later associated with the order.
---
`useApplyMetafieldsChange` is a React hook that lets you write metafield values. To learn more about the hooks available for Checkout UI extensions, refer to the [Checkout UI extension reference](/docs/api/checkout-ui-extensions/latest/react-hooks).
</If>
<If extension="javascript">
Use the `applyMetafieldChange` helper function of the `StandardApi` Checkout API object to store the value that the customer enters in the `metafields` property of the checkout. This metafield value is later associated with the order.
</If>
<If extension="react">
<Resources>
[useApplyMetafieldsChange](/docs/api/checkout-ui-extensions/latest/react-hooks/cart/useapplymetafieldschange)
</Resources>
</If>
<If extension="javascript">
<Resources>
[applyMetafieldChange](/docs/api/checkout-ui-extensions/latest/apis/standardapi#properties-propertydetail-applymetafieldchange)
[StandardApi](/docs/api/checkout-ui-extensions/latest/apis/standardapi)
</Resources>
</If>
</Substep>
</Step>
<Step>
## Show the note in the Shopify admin
After you've saved the note metafield to the order, display it on the order details page in the Shopify admin so that users can view it.
<Substep>
### Add a metafield definition in the Shopify admin
In the Shopify admin, add an **Order** [metafield definition](https://help.shopify.com/manual/custom-data/metafields/metafield-definitions/creating-custom-metafield-definitions) for your delivery instruction metafield. The type should be **Single line text**. Use the same `namespace` and `key` that you defined [in your <If extension="react">`Checkout.jsx`</If><If extension="javascript">`Checkout.js`</If> file](#set-up-a-metafield).
<Notice type="tip" title="Tip">
If you already placed an order with delivery instructions, then you might need to select the metafield from the [**Metafields without a definition** list](https://help.shopify.com/manual/custom-data/metafields/metafield-definitions/migrating-metafields-to-a-definition#definitions-for-existing-metafields).
</Notice>
</Substep>
</Step>
<Step>
<CheckoutUiPreview extension="field " extraInstruction={<Notice type="note">Your Provide delivery instructions checkbox should render in the Shipping step of the checkout. </Notice>}
/>
</Step>
<Step>
## Test the extension
Test your extension to make sure that it works as expected.
<Substep>
### Test the extension in the checkout
Place an order with delivery instructions in the checkout.
1. With your server running, open the storefront of your development store.
2. Add a product to the cart and then check out.
3. Fill out the contact and shipping address information, and then move to the **Shipping** step of the checkout.
Your **Provide delivery instructions** checkbox appears.
4. Select the **Provide delivery instructions** checkbox. A text field appears.
5. Enter a value in the text field and then complete the checkout.
6. In the Shopify admin for the development store, open the order details page for the order that you just placed.
The delivery instructions that you entered are displayed in the **Metafields** section, in the delivery instructions field that you created.
---
![Delivery instructions in the order details page.](/assets/apps/checkout/metafield.png)
</Substep>
</Step>
<Deploy />
</StepSection>
<NextSteps>
## Tutorial complete!
Nice work - what you just built could be used by Shopify merchants around the world! Keep the momentum going with these related tutorials and resources.
### Next steps
<CardGrid>
<LinkCard href="/docs/apps/checkout/custom/fields/ux-guidelines">
#### Review custom field UX guidelines
Build a user experience by following our UX guidelines.
</LinkCard>
<LinkCard href="/docs/apps/checkout/localizing-ui-extensions">
#### Localize your extension
Learn how to localize the text and number formats in your extension.
</LinkCard>
<LinkCard href="/docs/api/checkout-ui-extensions/latest/components">
#### Explore the checkout UI extension component reference
Learn about all of the components that you can use in your checkout UI extension.
</LinkCard>
<LinkCard href="/docs/api/checkout-ui-extensions/latest/apis/extensiontargets">
#### Explore the checkout UI extension targets API reference
Learn about the extension targets offered in the checkout.
</LinkCard>
</CardGrid>
</NextSteps>