Visibility for shop metafield on storefront API 2025-01

Hi,

Reaching out to look for support on how to make shop metafields available on the storefront api, v.2025-01
What I currently have is:
I created a metafield definition for a namespace that in theory allows storefront visibility:

#URL
https://{{my-domain}}/admin/api/2025-01/graphql.json

# GQL:
mutation CreateMetafieldDefinition($definition: MetafieldDefinitionInput!) {
  metafieldDefinitionCreate(definition: $definition) {
    createdDefinition {
      id
      name
    }
    userErrors {
      field
      message
      code
    }
  }
}

# Variables
{
	"definition": {
			"name": "A descriptive name",
			"namespace": "$app:jonh-doe",
			"key": "myapp-jonh-doe-definition-key",
			"type": "json",
			"ownerType": "SHOP",
			"access": {
				"admin": "MERCHANT_READ_WRITE",
				"storefront": "PUBLIC_READ"
			}
		}
}

Then I created a metafield on the same namespace using the following:

# URL
https://{{domain}}.myshopify.com/admin/api/2025-01/graphql.json

# GQL
mutation SetPromotionMetafield($metafieldInput: MetafieldsSetInput!) {
  metafieldsSet(metafields: [$metafieldInput]) {
    metafields {
      id
      namespace
      key
    }
    userErrors {
      field
      message
    }
  }
}

# Variables
{
  "metafieldInput": {
    "namespace": "$app:jonh-doe",
    "key": "AWSOME",
    "ownerId": "gid://shopify/Shop/<shopID>",
    "type": "json",
    "value": "{\"Hello\": \"World\"}"
  }
}

I can only see that the metafield was created on the admin API, but when I try to query it from the storefront API a have no results:

# URL
https://{{domain}}.myshopify.com/api/2025-01/graphql.json

# GQL
query ShopMetafield($namespace: String, $key: String!) {
  shop {
    metafield(namespace: $namespace, key: $key) {
        id
        key
        namespace
        updatedAt
        value
    }
  }
}

# Variables
{
  "namespace": "$app:jonh-doe",
  "key": "AWSOME"
}

# this returns:
{
    "data": {
        "shop": {
            "metafield": null
        }
    }
}

Any Ideas?

Hey @Alon_Mota_Lourenco, if you query metafields using just the key for identifiers, do you see anything returned at all?

Also double check that you have the necessary scopes for your app unauthenticated_read_product_listings is needed for the Shop object.

Hey @KyleG-Shopify , Thanks for the reply.
Where do I check for the unauthenticated_read_product_listings permission?

Sure, if I run the following query on the admin API:

# URL
https://{{domain}}.myshopify.com/admin/api/2025-01/graphql.json

# GQL
query ShopMetafield($namespace: String, $key: String!) {
  shop {
    metafield(namespace: $namespace, key: $key) {
            key
            namespace
            value
            ownerType
            owner {
                ... on Shop {
                    id
                    name
                }
            }
            definition {
                id
                access {
                    admin
                    storefront
                }
            }
        
    }
  }
}

# Variables
{
  "namespace":"$app:jonh-doe",
  "key": "AWSOME"
}

# I get the following response
{
    "data": {
        "shop": {
            "metafield": {
                "key": "AWSOME",
                "namespace": "app--<my-app-id>--jonh-doe",
                "value": "{\"hello\":\"world\"}",
                "ownerType": "SHOP",
                "owner": {
                    "id": "gid://shopify/Shop/<ShopId>",
                    "name": "<my-shop-name>"
                },
                "definition": null
            }
        }
    },
    "extensions": {
        "cost": {
            "requestedQueryCost": 5,
            "actualQueryCost": 4,
            "throttleStatus": {
                "maximumAvailable": 2000.0,
                "currentlyAvailable": 1996,
                "restoreRate": 100.0
            }
        }
    }
}

But if i ran it on the Storefront API I get:

# URL
https://{{domain}}.myshopify.com/api/2025-01/graphql.json

# GQL
query ShopMetafield {
  shop {
    metafields(identifiers: [{
        key: "AWSOME"
    }]) {
        id
        key
        namespace
        updatedAt
        value
    }
  }
}

# I get:
{
    "data": {
        "shop": {
            "metafields": [
                null
            ]
        }
    }
}

I notice that if I create the metafield first, and then create the definition with a matching namespace and key, the definition gets associated with the metafield and it becomes available on the storefront API. Is that the correct way to go about it?

My goal here was to make all metafields added to this namespace available on the storefront API. Will I need to create a separate definition for each one?

I think the issue is that the metafield definition and metafield are using different keys. If you use the same key for both, it should work as intended here. Was there an explicit reason to have these keys be different?

Hey @Matt_Koenig,
Yes, I was hoping that the definition would bind to all metafields on the namespace.

My goal ultimate goal here was to make all metafields added to this namespace available on the storefront API.

If I associate the definition to the metafield using the key, then I would need one definition per metafield, which would add a bit of complexity to maintaining these metafields.

Do you know if there is a way that I can have all metafields on a namespace available on the storefront api?

Oh interesting! We don’t have a namespace-wide setting like that. I’d create definitions for these (creating metafield definitions has its own benefits too!) and then make them storefront visible.

I see, thanks for the explanation.
I’ll move forward creating definitions per metafield then.
Appreciate the help.