---
title: Migrate translatable metafield queries
description: >-
  Learn how to migrate your app from the deprecated METAFIELD translatable
  resource type to the translatable field on metafields.
source_url:
  html: 'https://shopify.dev/docs/apps/build/markets/migrate-translatable-metafields'
  md: >-
    https://shopify.dev/docs/apps/build/markets/migrate-translatable-metafields.md
api_name: admin
---

# Migrate translatable metafield queries

The `METAFIELD` value of the [`TranslatableResourceType`](https://shopify.dev/docs/api/admin-graphql/latest/enums/TranslatableResourceType) enum is deprecated. Metafields are conditionally translatable: whether a metafield's value can be translated depends on the metafield's [type](https://shopify.dev/docs/apps/build/metafields/list-of-data-types#basic-types) and on whether its owner resource allows metafield translations. A shop-wide resource type can't express that condition, so your app had to cross-reference each metafield's type to determine what it could translate.

The [`Metafield.translatable`](https://shopify.dev/docs/api/admin-graphql/latest/objects/Metafield) field answers that question on the metafield itself. In this guide, you'll learn how to replace `translatableResources(resourceType: METAFIELD)` with a per-resource metafield query, and how to register translations for the translatable metafields that you find.

**Note:**

The `METAFIELD` value still works on every API version, and Shopify will announce its removal separately. Migrate now so that your app isn't affected when it's removed.

***

## Requirements

* Your app can make [authenticated requests](https://shopify.dev/docs/api/admin-graphql#authentication) to the GraphQL Admin API.
* Your app is on API version 2026-10 or higher. The `translatable` field isn't available in earlier versions.
* Your app has the `read_translations` and `write_translations` [access scopes](https://shopify.dev/docs/api/usage/access-scopes), and the read scope for each resource that owns the metafields that you translate. The examples in this guide query products, which require the `read_products` access scope. Learn how to [configure your access scopes using Shopify CLI](https://shopify.dev/docs/apps/build/cli-for-apps/app-configuration).
* Your app queries `translatableResources` or `translatableResourcesCount` with `resourceType: METAFIELD`.

***

## Considerations

* You can't filter a metafield query by `translatable`. Retrieve the metafields for a resource, and then filter the results in your app.
* No single query returns every translatable metafield in a shop. Query each resource type that your app translates. To scan an entire shop, you can use [bulk operations](https://shopify.dev/docs/api/usage/bulk-operations/queries).
* The `translatable` value reflects both the metafield's type and whether its owner allows metafield translations, so the same metafield type can be translatable on one resource and not translatable on another.
* The `translatable` field tells you which metafields you can translate, but it doesn't return the content digest that the [`translationsRegister`](https://shopify.dev/docs/api/admin-graphql/latest/mutations/translationsRegister) mutation requires. Retrieve digests with [`translatableResourcesByIds`](https://shopify.dev/docs/api/admin-graphql/latest/queries/translatableResourcesByIds), as shown in step 3. The `Metafield.compareDigest` field isn't a substitute, because it's computed differently and `translationsRegister` rejects it.

***

## Step 1: Replace the `translatableResources` query

Previously, you retrieved a shop's translatable metafields with the `translatableResources` query and `resourceType: METAFIELD`.

In API version 2026-10 and higher, query the metafields on the resource that owns them and select the `translatable` field. The following example retrieves the metafields for a product:

## POST https://{shop}.myshopify.com/api/{api\_version}/graphql.json

## GraphQL query

##### Deprecated

```graphql
{
  translatableResources(first: 10, resourceType: METAFIELD) {
    edges {
      node {
        resourceId
        translatableContent {
          key
          value
          digest
          locale
        }
      }
    }
  }
}
```

##### Replacement

```graphql
query ProductMetafields($id: ID!) {
  product(id: $id) {
    id
    metafields(first: 10) {
      edges {
        node {
          id
          namespace
          key
          type
          translatable
        }
      }
    }
  }
}
```

## Variables

```json
{
  "id": "gid://shopify/Product/1973887860758"
}
```

## JSON response

```json
{
  "data": {
    "product": {
      "id": "gid://shopify/Product/1973887860758",
      "metafields": {
        "edges": [
          {
            "node": {
              "id": "gid://shopify/Metafield/31183253700632",
              "namespace": "custom",
              "key": "care_instructions",
              "type": "multi_line_text_field",
              "translatable": true
            }
          },
          {
            "node": {
              "id": "gid://shopify/Metafield/31183253733400",
              "namespace": "custom",
              "key": "fabric_composition",
              "type": "single_line_text_field",
              "translatable": true
            }
          },
          {
            "node": {
              "id": "gid://shopify/Metafield/31183253766168",
              "namespace": "custom",
              "key": "launch_date",
              "type": "date",
              "translatable": false
            }
          }
        ]
      }
    }
  }
}
```

***

## Step 2: Filter for translatable metafields

Filter the response in your app and collect the IDs of the metafields where `translatable` is `true`. You'll use those IDs in the next step:

## Filter translatable metafields

```javascript
const metafields = response.data.product.metafields.edges.map((edge) => edge.node);


const translatableIds = metafields
  .filter((metafield) => metafield.translatable)
  .map((metafield) => metafield.id);


// ["gid://shopify/Metafield/31183253700632", "gid://shopify/Metafield/31183253733400"]
```

***

## Step 3: Retrieve the translatable content digests

The `translationsRegister` mutation requires a `translatableContentDigest` value for each value that you translate. Pass the metafield IDs from the previous step to the `translatableResourcesByIds` query to retrieve their digests in a single request.

A metafield exposes one translatable key, `value`:

## POST https://{shop}.myshopify.com/api/{api\_version}/graphql.json

## GraphQL query

```graphql
query MetafieldDigests($resourceIds: [ID!]!) {
  translatableResourcesByIds(first: 10, resourceIds: $resourceIds) {
    edges {
      node {
        resourceId
        translatableContent {
          key
          value
          digest
          locale
        }
      }
    }
  }
}
```

## Variables

```json
{
  "resourceIds": [
    "gid://shopify/Metafield/31183253700632",
    "gid://shopify/Metafield/31183253733400"
  ]
}
```

## JSON response

```json
{
  "data": {
    "translatableResourcesByIds": {
      "edges": [
        {
          "node": {
            "resourceId": "gid://shopify/Metafield/31183253700632",
            "translatableContent": [
              {
                "key": "value",
                "value": "Machine wash cold. Do not tumble dry.",
                "digest": "dcf8d211f6633dac78dbd15c219a81b8931e4141204d18fba8c477afd19b75f9",
                "locale": "en"
              }
            ]
          }
        },
        {
          "node": {
            "resourceId": "gid://shopify/Metafield/31183253733400",
            "translatableContent": [
              {
                "key": "value",
                "value": "100% organic cotton",
                "digest": "8e48350042b4ca04a7a4568774af71f921e7c9b561d9fac7860041e566218d25",
                "locale": "en"
              }
            ]
          }
        }
      ]
    }
  }
}
```

***

## Step 4: Register the translations

Use the `translationsRegister` mutation to write a translation for a metafield. Pass the metafield's ID as the `resourceId`, `value` as the `key`, and the digest from the previous step as the `translatableContentDigest`:

## POST https://{shop}.myshopify.com/api/{api\_version}/graphql.json

## GraphQL mutation

```graphql
mutation RegisterMetafieldTranslation($resourceId: ID!, $translations: [TranslationInput!]!) {
  translationsRegister(resourceId: $resourceId, translations: $translations) {
    userErrors {
      field
      message
    }
    translations {
      key
      locale
      value
    }
  }
}
```

## Variables

```json
{
  "resourceId": "gid://shopify/Metafield/31183253700632",
  "translations": [
    {
      "key": "value",
      "locale": "es",
      "value": "Lavar a máquina con agua fría. No secar en secadora.",
      "translatableContentDigest": "dcf8d211f6633dac78dbd15c219a81b8931e4141204d18fba8c477afd19b75f9"
    }
  ]
}
```

## JSON response

```json
{
  "data": {
    "translationsRegister": {
      "userErrors": [],
      "translations": [
        {
          "key": "value",
          "locale": "es",
          "value": "Lavar a máquina con agua fría. No secar en secadora."
        }
      ]
    }
  }
}
```

To verify a translation, query the metafield's [`translations`](https://shopify.dev/docs/api/admin-graphql/latest/objects/Metafield) field with the locale that you registered.

***

## Next steps

* Learn how to [manage translations of merchant-provided content](https://shopify.dev/docs/apps/build/markets/manage-translated-content) for other resource types.
* Review which [metafield data types](https://shopify.dev/docs/apps/build/metafields/list-of-data-types#basic-types) are translatable.
* Use the Storefront API to [retrieve translated content](https://shopify.dev/docs/storefronts/headless/building-with-the-storefront-api/markets/multiple-languages).

***
