---
title: Intents
description: >-
  Receive context from the Shop app when it launches your Mini to handle a
  specific action, such as a virtual try-on for a selected product.
source_url:
  html: 'https://shopify.dev/docs/api/shop-minis/intents'
  md: 'https://shopify.dev/docs/api/shop-minis/intents.md'
---

# Intents

Intents are a communication mechanism between the Shop app and Shop Minis. One side describes an action and the other handles it and returns a result. For example, when a user wants to virtually try on a product, the Shop app launches a Mini with a try-on feature, passing it the product as context.

Eventually, intents will flow in three directions: the Shop app launching a Mini, your Mini invoking workflows in the Shop app (such as a product picker), and one Mini invoking another. Each Mini will also declare which intents it can handle, so the Shop app knows which one to launch.

Today, only the first direction works: the Shop app passes intent context as query parameters on the launch URL, and your Mini reads them with the `useIntent` hook. The rest of this guide covers that flow.

***

## How intents work

When the Shop app launches your Mini to handle an intent, it appends two query parameters to the launch URL:

* **`intentQuery`**: A string describing the action and its target, using the format `action:type,value`. For example, `try_on:shopify/Product,gid://shopify/Product/123`.
* **`intentData`**: An optional JSON-stringified object carrying additional context for the action, such as a selected variant.

Your Mini reads the intent with the [`useIntent`](https://shopify.dev/docs/api/shop-minis/hooks/intents/useintent) hook. The hook parses `intentQuery` into a `query` object with `action`, `type`, and `value` fields, and parses `intentData` into `data`.

Intent query parameters aren't tied to a specific path. `useIntent` reads them regardless of the URL's path, so intents can travel alongside a [deeplink](https://shopify.dev/docs/api/shop-minis/deeplinks) path on the same URL.

***

## Handling an intent in your Mini

Call `useIntent` to read the intent passed to your Mini. `query` is `null` when your Mini wasn't launched with an intent, so guard for that before acting. Check `query.action` and `query.type` to decide what to do, then read the context from `query.value` and `data`:

## Reading an intent

```tsx
import {useMemo} from 'react'
import {useIntent} from '@shopify/shop-minis-react'


export function useTryOnIntent() {
  const {query, data} = useIntent()


  return useMemo(() => {
    if (!query) return null
    if (query.action !== 'try_on') return null
    if (query.type !== 'shopify/Product') return null


    const productGid = query.value
    const variantGid =
      typeof data?.variantId === 'string' ? data.variantId : null


    return {productGid, variantGid}
  }, [query, data])
}
```

[API Reference - useIntent API](https://shopify.dev/docs/api/shop-minis/hooks/intents/useintent)

***

## Intent URI format

The `intentQuery` parameter uses the URI format `action:type,value`:

* **`action`**: A verb describing what the user wants to do, such as `try_on` or `view_in_room`.
* **`type`**: The kind of resource the action targets, typically a Shopify resource type like `shopify/Product`.
* **`value`**: The identifier of the resource, typically a [GID](https://shopify.dev/docs/api/usage/gids).

### GID shorthand

When `value` is a Shopify GID, you can omit the explicit `type` and pass the GID directly after the action. `useIntent` derives `query.type` from the GID's type segment. For example, `try_on:gid://shopify/Product/123` parses as:

* `query.action`: `try_on`
* `query.type`: `shopify/Product`
* `query.value`: `gid://shopify/Product/123`

***

## Intents vs.​deeplinks

Intents and [deeplinks](https://shopify.dev/docs/api/shop-minis/deeplinks) are both entry points into your Mini, but they serve different purposes.

* Deeplinks navigate to a specific path inside your Mini, such as `/recipe/123`. Use deeplinks when an external source needs to open a particular screen.
* Intents describe a contextual action the host wants your Mini to handle, with structured data attached. Use intents when the host has context about what the user wants to accomplish.

The two aren't mutually exclusive. Intent query parameters can travel alongside a deeplink path on the same URL, and `useIntent` reads them regardless of the path.

***

## Testing during development

Test an intent by opening your Mini with a URL that includes `intentQuery` and `intentData` as query parameters, then use the [deeplink testing flow](https://shopify.dev/docs/api/shop-minis/deeplinks#testing-deeplinks-during-development): press `d` in the dev terminal, or enter the URL as the **Initial Path** in the QR code page.

Because `intentQuery` uses `:` and `,` as delimiters and GID values contain `/`, URL-encode each query parameter value. `intentData` is a JSON-stringified object, so encode its `{`, `"`, and `:` characters too.

The following URL encodes `view_in_room:gid://shopify/Product/123` as `intentQuery` and `{"variantId":"gid://shopify/ProductVariant/456"}` as `intentData`:

## Encoded intent URL

```txt
https://shop.app/mini/my-mini/?intentQuery=view_in_room%3Agid%3A%2F%2Fshopify%2FProduct%2F123&intentData=%7B%22variantId%22%3A%22gid%3A%2F%2Fshopify%2FProductVariant%2F456%22%7D
```

To avoid hand-encoding, build the URL with the `URL` API:

## Building an intent URL

```tsx
const url = new URL('https://shop.app/mini/my-mini/')
url.searchParams.set('intentQuery', 'view_in_room:gid://shopify/Product/123')
url.searchParams.set(
  'intentData',
  JSON.stringify({variantId: 'gid://shopify/ProductVariant/456'}),
)
```

***
