---
title: Use variables in input queries
description: Learn how to use variables in input queries with Shopify Functions.
source_url:
  html: >-
    https://shopify.dev/docs/apps/build/functions/input-queries/use-variables-input-queries
  md: >-
    https://shopify.dev/docs/apps/build/functions/input-queries/use-variables-input-queries.md
api_type: functions
---

# Use variables in input queries

Function input queries can be customized on each [function owner](https://shopify.dev/docs/apps/build/functions/input-queries/metafields-for-input-queries#how-it-works) using input query variables. This is helpful when using fields with arguments like [`inAnyCollection`](https://shopify.dev/docs/api/functions/reference/order-discounts/graphql/common-objects/product).

For example, consider the following input query:

## without-input-query-variables.graphql

```graphql
query Input {
  cart {
    lines {
      id
      merchandise {
        ... on ProductVariant {
          id
          product {
            inExcludedCollection: inAnyCollection(ids: ["gid://shopify/Collection/1", "gid://shopify/Collection/2", "gid://shopify/Collection/3"])
            inVIPCollection: inAnyCollection(ids: ["gid://shopify/Collection/4", "gid://shopify/Collection/5"])
          }
        }
      }
    }
  }
}
```

This input query will only work on the shop where those collections are defined, limiting the function to single shop. Additionally, there's no way to update these collections without deploying a new version of the function with an updated input query, or to vary them when your function is used multiple times in a shop.

This guide will explain how to use input query variables to make these arguments configurable.

***

## Requirements

* You're using Shopify CLI 4.9.0 or higher. Learn how to [upgrade Shopify CLI](https://shopify.dev/docs/api/shopify-cli#upgrade).
* You're familiar with [metafields](https://shopify.dev/docs/apps/build/custom-data/metafields) concepts and APIs.
* You're familiar with the use of [metafields to configure functions](https://shopify.dev/docs/apps/build/functions/input-queries/metafields-for-input-queries)

***

## Step 1: Specify variables for your query

Replace field argument values with a variable with a matching type. In the case of the `ids` argument of `inAnyCollection`, the type is `[ID!]`.

## with-input-query-variables.graphql

```graphql
query Input($excludedCollectionIds: [ID!], $vipCollectionIds: [ID!]) {
  cart {
    lines {
      id
      merchandise {
        ... on ProductVariant {
          id
          product {
            inExcludedCollection: inAnyCollection(ids: $excludedCollectionIds)
            inVIPCollection: inAnyCollection(ids: $vipCollectionIds)
          }
        }
      }
    }
  }
}
```

***

## Step 2: Specify values for variables

Input query variables are populated by reading a [JSON metafield](https://shopify.dev/docs/apps/build/custom-data/metafields/list-of-data-types) on the [function owner](https://shopify.dev/docs/apps/build/functions/input-queries/metafields-for-input-queries#how-it-works). The structure of the metafield value must be such that each top level key corresponds to a variable name, and each value matches that variables type. To satisfy the query above, we need to set a metafield value like this:

```json
{
  "excludedCollectionIds": [
    "gid://shopify/Collection/1",
    "gid://shopify/Collection/2",
    "gid://shopify/Collection/3"
  ],
  "vipCollectionIds": [
    "gid://shopify/Collection/4",
    "gid://shopify/Collection/5"
  ]
}
```

**Tip:**

For any variables which do not appear as top level keys in the metafield, a value of `null` will be used. Similarly, if the metafield is not set, all variables will use a value of `null`. If a variable is declared as required using the `!` suffix, and a value of `null` is passed, function execution will fail.

The metafield will be read from the [function owner](https://shopify.dev/docs/apps/build/functions/input-queries/metafields-for-input-queries#how-it-works) at runtime to populate the values for these variables. You can set this metafield using the same techniques as you would for configuration you would access in the function. To illustrate our example, we'll use the [`metafieldsSet`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/metafieldsSet) mutation:

## set-metafield.graphql

```graphql
mutation SetMetafield {
  metafieldsSet(metafields: [
    {
      namespace: "$app:my-namespace",
      key: "my-key",
      ownerId: "OWNER_ID",
      type: "json",
      value: "{\"excludedCollectionIds\":[\"gid://shopify/Collection/1\",\"gid://shopify/Collection/2\",\"gid://shopify/Collection/3\"],\"vipCollectionIds\":[\"gid://shopify/Collection/4\",\"gid://shopify/Collection/5\"]}"
    }
  ]) {
    metafields {
      id
    }
  }
}
```

**Caution:**

Ensure you set metafields on the function owner. For example, Discount API variables would be set on the [discount](https://shopify.dev/docs/api/admin-graphql/2024-07/enums/MetafieldOwnerType#value-discount), Checkout Validation API variables would be set on the [validation](https://shopify.dev/docs/api/admin-graphql/2024-07/enums/MetafieldOwnerType#value-validation), Cart Transform API variables would be set on the [cart transform](https://shopify.dev/docs/api/admin-graphql/2024-07/enums/MetafieldOwnerType#value-carttransform), and so on. Input query variables do not utilize metafields on the shop or app installation.

You should use a [reserved prefix](https://shopify.dev/docs/apps/build/custom-data/ownership#reserved-prefixes) in your metafield namespace so that other apps can't use your metafields.

***

## Step 3: Specify which metafield to use for input queries

To specify which metafield contains the input query variables, set `input_variables` on the target in the function's [configuration file](https://shopify.dev/docs/api/functions/latest#configuration). Add it next to the target's `input_query`:

## shopify.extension.toml

```toml
[[extensions.targeting]]
target = "cart.lines.discounts.generate.run"
input_query = "src/cart_lines_discounts_generate_run.graphql"
input_variables = { namespace = "$app:my-namespace", key = "my-key" }
export = "cart_lines_discounts_generate_run"
```

A target's `input_variables` applies only to that target's input query. Your function fails to deploy if either of the following is true:

* A target's input query declares variables, but the target doesn't have `input_variables`.
* A target has `input_variables`, but its input query doesn't declare any variables.

If your function has multiple targets, then each target can use its own metafield:

## shopify.extension.toml

```toml
[[extensions.targeting]]
target = "cart.lines.discounts.generate.run"
input_query = "src/cart_lines_discounts_generate_run.graphql"
input_variables = { namespace = "$app:my-namespace", key = "cart-lines-variables" }
export = "cart_lines_discounts_generate_run"


[[extensions.targeting]]
target = "cart.delivery-options.discounts.generate.run"
input_query = "src/cart_delivery_options_discounts_generate_run.graphql"
input_variables = { namespace = "$app:my-namespace", key = "delivery-options-variables" }
export = "cart_delivery_options_discounts_generate_run"
```

Targets can also use the same metafield. Each input query uses only the variables that it declares.

After you deploy this configuration, your function loads the metafield at runtime to populate your input query variables.

### Migrate from extension-level variables

**Deprecated:**

Extension-level input query variables, configured in `[extensions.input.variables]`, are deprecated. Use target-level `input_variables` for new and existing functions.

Extension-level variables apply one metafield to every target. To move them onto your targets, complete the following steps:

1. [Upgrade](https://shopify.dev/docs/api/shopify-cli#upgrade) to Shopify CLI 4.9.0 or higher.
2. Remove the `[extensions.input.variables]` section from your `shopify.extension.toml` file.
3. Add `input_variables` with the same `namespace` and `key` to each target whose input query declares variables. You don't need to change the metafield.
4. Deploy your function.

You can't declare variables at both levels in the same function. If your configuration has both `[extensions.input.variables]` and `input_variables` on a target, then the deploy fails.

If you're using an earlier version of the configuration file that doesn't have an `[[extensions]]` section, then the extension-level section is called `[input.variables]`, and you add `input_variables` to each `[[targeting]]` entry whose input query declares variables.

***

## Limitations

* Only JSON type metafields are supported.
* Metafields above the size [limit](https://shopify.dev/docs/api/functions/latest#input-query-limits) won't be returned. The function should use separate metafields in these cases.
* Input query variables will return errors for any [GraphQL list](https://graphql.org/learn/schema/#lists-and-non-null) variable with a value that exceeds 100 elements.

***

## Next steps

* Learn about the [language support](https://shopify.dev/docs/apps/build/functions/programming-languages) available in Shopify Functions.
* Consult the [API references for Shopify Functions](https://shopify.dev/docs/api/functions).

***
