This guide shows you how to add a customized bundle using [Shopify Functions](/docs/apps/build/functions). ## What you'll learn In this tutorial, you'll learn how to do the following tasks: - Set up your environment to use functions. - Create a [`cart_transform` function](/docs/api/functions/reference/cart-transform). ## Requirements - You've created a [Partner account](https://www.shopify.com/partners). - You've created a [development store](/docs/api/development-stores#create-a-development-store-to-test-your-app). - You've [created an app that uses Shopify CLI 3.49.5 or higher](/docs/apps/build/scaffold-app). If you previously installed Shopify CLI, then make sure that you're using the [latest version](/docs/api/shopify-cli#upgrade). If you plan to create a UI for your extension, then start with the [Remix app template](/docs/api#app-templates). - You've installed [Node.js](https://nodejs.org/en/download) 16 or higher. - You've [installed your app](/docs/apps/build/scaffold-app#step-3-install-your-app-on-your-development-store) on the development store. - You're familiar with the [Cart Transform Function API](/docs/api/functions/reference/cart-transform). ### Rust-specific requirements The following requirements are specific to Rust-based development with Shopify Functions. - You've installed [Rust](https://www.rust-lang.org/tools/install). On Windows, Rust requires the [Microsoft C++ Build Tools](https://docs.microsoft.com/en-us/windows/dev-environment/rust/setup). Make sure to select the **Desktop development with C++** workload when installing the tools. - You've installed the [`wasm32-wasip1` target](https://doc.rust-lang.org/rustc/platform-support/wasm32-wasip1.html):

## Limitations and considerations - A bundle can have up to 150 components. - After an app has assigned components to a bundle, only that app can manage the components of the bundle. - Nested bundles aren't supported. A bundle can't have components and be part of another bundle simultaneously. ## Step 1: Generate a new extension To create a cart transform extension, you can use Shopify CLI, which generates starter code for building your extension and automates common development tasks. 1. Navigate to your app directory:

2. Run the following command to create the app extension:

1. Choose the language that you want to use. For this tutorial, you should select either **Rust** or **JavaScript**. Shopify defaults to Rust as the most performant and recommended language choice to stay within the platform limits. For more information, refer to [language considerations](/docs/apps/build/functions/programming-languages).

4. Navigate to `extensions/demo-cart-transform-extension`:

## Step 2: Define the input of your function `run.graphql` defines the input for the function [`target`](https://shopify.dev/docs/api/functions/reference/cart-transform/graphql#extension-targets). The following example shows an input that retrieves information about buyer's cart like merchandise, quantity etc. Replace the contents of `src/run.graphql` file with the following code.

The [`Function API references`](docs/api/functions/reference/cart-transform/graphql/input) provide information on the available fields for the input query. > Note: > `CartTransform` only supports a subset of cart fields. For the list of supported cart fields, refer to the [`cart`](docs/api/functions/reference/cart-transform/graphql/common-objects/cart) input field. ## Step 3: Define the business logic of your function In this example, our function will output expand operations for cart lines where merchandise has a metafield referencing other bundle components. Replace the contents of `src/run.rs` file with the following code.

> Tip: > Explore more examples in the [`function-examples` repository](https://github.com/Shopify/function-examples/tree/main/sample-apps). > Caution: > Don't rely on cart line attributes to validate the composition of the bundle, as they can be modified by the browser. We recommend using metafields for this purpose instead. ## Step 4: Update your app access scopes You need to request the `write_cart_transforms` and `write_products` [access scopes](/docs/api/usage/access-scopes) to run the mutations in this guide. 1. In `shopify.app.toml` in the root of your app, add the `write_cart_transforms` scope.

1. Deploy your updated configuration to Shopify:

1. Restart your app.

1. Use the URL provided by the CLI to open and re-install your app. You should be prompted to accept the new access scope permissions in your store. ## Step 5: Create the cartTransform object To activate your function, create a [`cartTransform`](/docs/api/admin-graphql/unstable/objects/CartTransform) object on the store where you installed your app. You can do this using the [`cartTransformCreate`](/docs/api/admin-graphql/unstable/mutations/cartTransformCreate) GraphQL mutation. > Note: > You can use [curl](/docs/api/admin-graphql) to make following GraphQL requests. > Only use the access token of the app for which you are building this extension. 1. Find the ID of your function by executing the following query:

The result contains a node with your function's ID:

1. Run the following mutation. Replace `YOUR_FUNCTION_ID_HERE` with the ID of your function:

You should receive a GraphQL response that includes the ID of the new `cartTransform` object. > Tip: > If the mutation returns a `Could not find Function` error, then confirm that the function ID is correct, that you've installed the app on your development store, and that your app has the `write_cart_transforms` access scope. ## Step 6: Create metafield definition to store bundle components.

## Step 7: Create bundle products along with the components. In this tutorial, we will take the example of a meal bundle which contains a burger and fries. > Note: > You can use [curl](/docs/api/admin-graphql) to make following GraphQL requests. > Only use access token of the app for which you are building this extension. 1. Create bundle component products, i.e. burger and fries.

2. Create a bundle parent product, i.e. Meal Bundle. This example sets [`requires_components`](/docs/api/admin-graphql/unstable/objects/ProductVariant#field-productvariant-requiresComponents) on the variant of the bundle to `true`. This is required when the variants is meant to be sold as a bundle only. It prevents the variant from being sold as a regular product in case the function doesn't output an operation. For example, the variant `Meal Bundle` should always be sold as a bundle with components and not as a regular product.

> Note: > We are claiming the ownership of the bundle parent product here. This is required if you need to render the [product configuration extension](/docs/apps/build/product-merchandising/bundles/add-merchant-config-ui) in admin. ## Step 8: Install the extension on a development store > Note: > You can skip this step if you have already reinstalled the app on your store in step 4. To test your function, you need to make it available to your development store. 1. If you're developing a function in a language other than JavaScript or TypeScript, ensure you have configured `build.watch` in your [function extension configuration](/docs/api/functions/configuration#properties). 1. Navigate back to your app root:

1. Use the Shopify CLI [`dev` command](/docs/api/shopify-cli/app/app-dev) to start app preview:

You can keep the preview running as you work on your function. When you make changes to a watched file, Shopify CLI rebuilds your function and updates the function extension's drafts, so you can immediately test your changes. 1. Follow the CLI prompts to preview your app, and install it on your development store. ## Step 9: Preview the function Follow the steps below to test your function on your development store. 1. Navigate to your online storefront. 2. Add the meal bundle product to your cart. 3. Navigate to checkout. 4. You will now see that your meal bundle product is converted into a bundle which includes a burger and fries. ![An image showing a checkout including customized bundle.](/assets/apps/bundles/function-customized-bundle-checkout.png) ## Step 10: Deploy the extension When you're ready to release your changes to users, you can create and release an [app version](/docs/apps/launch/deployment/app-versions). An app version is a snapshot of your app configuration and all extensions. 1. Navigate to your app directory. 2. Run the following command. Optionally, you can provide a name or message for the version using the `--version` and `--message` flags.

Releasing an app version replaces the current active version that's served to stores that have your app installed. It might take several minutes for app users to be upgraded to the new version. > Tip: > If you want to create a version, but avoid releasing it to users, then run the `deploy` command with a `--no-release` flag. > > You can release the unreleased app version using Shopify CLI's [`release`](/docs/api/shopify-cli/app/app-release) command, or through the Partner Dashboard. ## Next steps - Learn how to [add a product configuration extension for bundles](/docs/apps/build/product-merchandising/bundles/add-merchant-config-ui) in the Shopify admin. - Learn how to use [variables](/docs/apps/build/functions/input-output/use-variables-input-queries) in your input query.