Have your say in Community Polls: What was/is your greatest motivation to start your own business?

Re: How to access App-data metafields from checkout ui extension.

How to access App-data metafields from checkout ui extension.

Evgeniy-M
Shopify Partner
44 6 10

Hey,

I keep app's data in App-data metafields but apparently it is not possible to access them in Checkout UI extension. Could you guys confirm that it is not possible, or i'm doing something wrong.

 

This is how I write to metafields: https://shopify.dev/docs/apps/custom-data/metafields/app-data

This is how I read them within the app and it works fine: https://shopify.dev/docs/api/admin-graphql/2023-01/queries/appInstallation#examples-Get_metafields_a... 

This is how I try to get access to them in checkout ui ext:

 

[[metafields]]
namespace = "mynamespace"
key = "mykey1"

[[metafields]]
namespace = "mynamespace"
key = "mykey2"

Then I try to read them within extension:

// first way 
const {appMetafields} = useExtensionApi();

// another way
const metafields = useAppMetafields();

Both ways didn't work for me.

 

 

Liquid Ajax Cart — a Javascript library to build Shopify Ajax Carts using plain Liquid templates.
Replies 22 (22)

DavidT
Shopify Partner
38 2 16

I'm looking to see if this is possible. Did you get this working?

QuickEdit - Bulk Product Edit - Quick and easy bulk editor for products, variants, and collections.
SafeShip - Address Validator - International address validation and PO box blocking at checkout for Shopify Plus merchants.

DavidT
Shopify Partner
38 2 16

So it appears that the unfortunately named AppMetafields is actually not referring to app metafields, but metafields on the relevant Shop, Customer, Product, or Variant.

QuickEdit - Bulk Product Edit - Quick and easy bulk editor for products, variants, and collections.
SafeShip - Address Validator - International address validation and PO box blocking at checkout for Shopify Plus merchants.
Evgeniy-M
Shopify Partner
44 6 10

Unfortunately yes. I ended up using Shop metafields as it seems not possible to get access to the app metafields from an extension.
@DavidT 

Liquid Ajax Cart — a Javascript library to build Shopify Ajax Carts using plain Liquid templates.
DavidT
Shopify Partner
38 2 16

I'm wondering if it's possible to use the Storefront API to fetch the metafields on the Shop but using reserved prefixes to protect the metafields from being changed by other apps.

QuickEdit - Bulk Product Edit - Quick and easy bulk editor for products, variants, and collections.
SafeShip - Address Validator - International address validation and PO box blocking at checkout for Shopify Plus merchants.
Evgeniy-M
Shopify Partner
44 6 10

@DavidT Never tried. So you need to have access to the same global metafields from your app, checkout ui extension and Storefront API? Let me know if you find a solution for it.

Liquid Ajax Cart — a Javascript library to build Shopify Ajax Carts using plain Liquid templates.
RhiRo
Shopify Partner
41 3 8

Could you advise how you did this? 
I'm having trouble getting anything but undefined when using the useAppMetafields react hook. I'm unsure of how to format the filters. 
Thanks so much! 

Rhianna

RhiRo
Shopify Partner
41 3 8

Scratch that, figured it out haha 👍

captainkoder
Shopify Partner
6 0 1

How did you solve this issue. I keep getting empty array when i use  useAppMetafileds()

Turbofan1178
Shopify Partner
57 4 10

@RhiRo How did you resolve this issue. Can you please paste sample code. Thanks.

Founder, WC: Invite To WhatsApp Channel
- Invite customers to join your WhatsApp channel with a single click
- Boost outreach message open rates
- Grow sales with direct outreach on WhatsApp channels
LouiseEH
Shopify Partner
38 3 7

In the shopify.extension.toml:

[[extensions.metafields]]
namespace = "some_namespace"
key = "some_key"

In the Checkout.jsx you import useAppMetafields.
The code could e.g. be:

...

const appMetafields = useAppMetafields()

...
console.log('appMetafields',appMetafields)

const myMetafield = appMetafields.filter(appMetafield => appMetafield.metafield.namespace =='some_namespace' && appMetafield.metafield.key =='some_key')

 




Turbofan1178
Shopify Partner
57 4 10

Yeah I understand that part. But how do you add the data to the metafields from an embedded app, for example if you want the merchant to make configurations that will be used in the checkout ui extension?

Founder, WC: Invite To WhatsApp Channel
- Invite customers to join your WhatsApp channel with a single click
- Boost outreach message open rates
- Grow sales with direct outreach on WhatsApp channels
LouiseEH
Shopify Partner
38 3 7

I am not sure I understand your question, but in general you can add UI to the embedded app that allows the merchant to configure different parameters. You can set those settings in metafields with the graphql mutation metafieldsset c.f. https://shopify.dev/docs/api/admin-graphql/2024-01/mutations/metafieldsset

Turbofan1178
Shopify Partner
57 4 10

This is what I'm currently doing in my embedded app; app._index.jsx:

 

const createMetafieldDefinitionMutation = await admin.graphql(
        `#graphql
          mutation CreateMetafieldDefinition($definition: MetafieldDefinitionInput!) {
            metafieldDefinitionCreate(definition: $definition) {
              createdDefinition {
                id
                name
                namespace
                key
              }
              userErrors {
                field
                message
                code
              }
            }
          }
        `,
        {
          variables: {
            "definition": {
                "name": "Ingredients",
                "namespace": "$app:test_secret_keys",
                "key": "ingredients",
                "description": "A list of ingredients used to make the product.",
                "type": "single_line_text_field",
                "ownerType": "SHOP"
              }
            
          }
        }
      );

 

 

And in shopify.extension.toml:

 

[[extensions.metafields]]
namespace = "test_secret_keys"
key = "ingredients"

 

 

And in Checkout.jsx:

 

const metafields = useAppMetafields()
console.log(metafields) // Returns an empty array []

 

I got the idea to use "SHOP" as the ownerType because of this post: https://github.com/Shopify/ui-extensions/discussions/1031

 

Founder, WC: Invite To WhatsApp Channel
- Invite customers to join your WhatsApp channel with a single click
- Boost outreach message open rates
- Grow sales with direct outreach on WhatsApp channels
LouiseEH
Shopify Partner
38 3 7

No you are using "metafieldDefinitionCreate" - this just creates a metafield definition for you to see in the admin under Settings -> Custom data, but it does not set a value in the metafield. If you want to set a value in the metafield, you should use the graphql mutation metafieldsset c.f. https://shopify.dev/docs/api/admin-graphql/2024-01/mutations/metafieldsset

Turbofan1178
Shopify Partner
57 4 10

This is what I've now in the embedded app side but I'm still getting an empty array on the checkout ui extension.

const currentAppInstallationQuery = await admin.graphql(
        `#graphql
          query {
            currentAppInstallation {
              id
            }
          }
        `
      );

      const currentAppInstallationQueryResponseJson = await currentAppInstallationQuery.json();
      const currentAppInstallationId = currentAppInstallationQueryResponseJson.data?.currentAppInstallation?.id
      
      const createAppDataMetafieldMutation = await admin.graphql(
        `#graphql
          mutation CreateAppDataMetafield($metafieldsSetInput: [MetafieldsSetInput!]!) {
            metafieldsSet(metafields: $metafieldsSetInput) {
              metafields {
                id
                namespace
                key
              }
              useErrors {
                field
                message
              }
            }
          }
        `,
        {
          variables: {
            "metafieldsSetInput": [
              {
                "namespace": "test_secret_keys",
                "key": "test_api_key",
                "type": "single_line_text_field",
                "value": "aS1hbS1hLXNlY3JldC1hcGkta2V5Cg==",
                "ownerId": currentAppInstallationId
              }
            ]
          }
        }
      );

 

 

And accessing it in shopify.extension.toml

[[extensions.metafields]]
namespace = "test_secret_keys"
key = "test_api_key"
Founder, WC: Invite To WhatsApp Channel
- Invite customers to join your WhatsApp channel with a single click
- Boost outreach message open rates
- Grow sales with direct outreach on WhatsApp channels
LouiseEH
Shopify Partner
38 3 7

Ensure that data is actually set - I don't know whether you check the response from metafieldsSet to determine whether an error occurred.
But you can go into the admin -> Settings -> Custom data -> Shop and manually set a value in you metafield and then test whether you can access the value in the UI extension

Turbofan1178
Shopify Partner
57 4 10

Okay, it appears to be showing now when I use the shop.id as the ownerId in the graphql metafieldsSet mutation. But now I'm wondering how I can create the metafield under a reserved namespace so that other apps aren't able to modify my app's data like it's done here: https://shopify.dev/docs/apps/custom-data/ownership. I tried what was instructed in the guide but that didn't work.

 

      const createAppDataMetafieldMutation = await admin.graphql(
        `#graphql
          mutation CreateAppDataMetafield($metafieldsSetInput: [MetafieldsSetInput!]!) {
            metafieldsSet(metafields: $metafieldsSetInput) {
              metafields {
                id
                namespace
                key
                value
                createdAt
                updatedAt
              }
              userErrors {
                field
                message
              }
            }
          }
        `,
        {
          variables: {
            "metafieldsSetInput": [
              {
                "namespace": "$app:test_secret_keys_1",
                "key": "test_api_key_1",
                "type": "single_line_text_field",
                "value": "aS1hbS1hLXNlY3JldC1hcGkta2V5Cg==",
                "ownerId": shopId
              }
            ]
          }
        }
      );

Here's what I have so far. 

Founder, WC: Invite To WhatsApp Channel
- Invite customers to join your WhatsApp channel with a single click
- Boost outreach message open rates
- Grow sales with direct outreach on WhatsApp channels
LouiseEH
Shopify Partner
38 3 7

I have not tried out the reserved namespaces myself yet, but I believe I saw somewhere that you can leave the namespace out and then the reserved namespace will be used by default. You should delete the defined metafield first - you can do it via the UI - remember to delete the values as well.

jfivedev
Shopify Partner
1 0 0

You were able to see metafields using the useAppMetafields hook with this approach?

I have not been able see any metafields with $app name space. 

I've also explored the reserved namespace route and receive an error when trying to set access through the CreateMetafieldDefinition mutation.

"Setting access controls on a definition under this namespace is not permitted."

Note on leaving namespace out: Using the metafieldsSet mutation and leaving out namespace defaults to $app namespace. Which again is not accessible through the hook.
RhiRo
Shopify Partner
41 3 8

Hi Turbofan, 

 

Sorry I'm a bit out of practice with checkout extensions, as I haven't looked at them for about 6 months. 
If I'm understanding the issue you're having (which I'm not sure I am haha), I think it might be helpful to look at Nicks answer to this post I made when I was having issues. 

LouiseEH
Shopify Partner
38 3 7

I think the configuration in the toml file should be [[extensions.metafields]] or [[extensions.targeting-metafields]], but I have not yet found a way to make it work.
Did you succeed in getting it to work?

Evgeniy-M
Shopify Partner
44 6 10

At the point when I was working on that, there were another API version:

https://shopify.dev/docs/api/checkout-ui-extensions/2023-04/configuration

 

If you manage to make it work with the new API version, let us know 🙂 

Liquid Ajax Cart — a Javascript library to build Shopify Ajax Carts using plain Liquid templates.