Skip to main content

Migrate translatable metafield queries

The METAFIELD value of the TranslatableResourceType enum is deprecated. Metafields are conditionally translatable: whether a metafield's value can be translated depends on the metafield's type 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 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.


  • Your app can make authenticated requests 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, 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.
  • Your app queries translatableResources or translatableResourcesCount with resourceType: METAFIELD.

  • 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.
  • 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 mutation requires. Retrieve digests with translatableResourcesByIds, as shown in step 3. The Metafield.compareDigest field isn't a substitute, because it's computed differently and translationsRegister rejects it.

Anchor to Step 1: Replace the ,[object Object], queryStep 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

{
translatableResources(first: 10, resourceType: METAFIELD) {
edges {
node {
resourceId
translatableContent {
key
value
digest
locale
}
}
}
}
}
query ProductMetafields($id: ID!) {
product(id: $id) {
id
metafields(first: 10) {
edges {
node {
id
namespace
key
type
translatable
}
}
}
}
}

Variables

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

JSON response

{
"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
}
}
]
}
}
}
}

Anchor to Step 2: Filter for translatable metafieldsStep 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

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"]

Anchor to Step 3: Retrieve the translatable content digestsStep 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

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

Variables

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

JSON response

{
"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"
}
]
}
}
]
}
}
}

Anchor to Step 4: Register the translationsStep 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

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

Variables

{
"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

{
"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 field with the locale that you registered.



Was this page helpful?