Conversations about creating, managing, and using metafields to store and retrieve custom data for apps and themes.
Hi there!
I am working on building an app which creates custom metaobject definition and objects using the Admin API / GraphQL. I cannot figure out how to access it from my Theme App Extension / Embed? From the documentation (The Documentation), it seemed like I should be able to add the storefront access as seen below in the definition.
I verified via my API that I can create/edit/retrieve objects, and that they are set to published status 'ACTIVE'.
The definition is below:
{
name: "xxxxxxxxxx",
type: "$app:xxxxxxxxxx",
description: "xxxxxxxxxx",
fieldDefinitions: [
{
description: "xxxxxxxxxx",
key: "xxxxxxxxxx_json",
name: "xxxxxxxxxx JSON",
required: true,
type: "json",
validations: [],
},
],
access: {
admin: "MERCHANT_READ",
storefront: "PUBLIC_READ",
},
capabilities: {
publishable: {
enabled: true,
},
translatable: {
enabled: false,
},
},
}
I feel like I have tried every combination of liquid similar to the following:
{{ shop.metaobjects['type'].values }}
{{ app.metaobjects['type'].values }}
{{ shop.metaobjects['$app:type'].values }}
{{ app.metaobjects['$app:type'].values }}
{{ app.metafields.values }}
EDIT: Adding link to another developer's post explaining the exact issue wwe are seeing: How to access app owned meta object in theme app extensions's liquid file?
https://community.shopify.com/c/technical-q-a/how-to-access-app-owned-meta-object-in-theme-app-exten...
Hi RiptideApps,
Have you tried this format to access an app's metafields in Liquid:
{{ app.metafields.namespace.key }}
Liam | Developer Advocate @ Shopify
- Was my reply helpful? Click Like to let me know!
- Was your question answered? Mark it as an Accepted Solution
- To learn more visit Shopify.dev or the Shopify Web Design and Development Blog
So, based on this metaobject data (retrieved from GraphQL API), I tried the following combinations...
{
capabilities: {
publishable: {
status: "ACTIVE",
},
},
definition: {
id: "gid://shopify/MetaobjectDefinition/XXXXXXX",
name: "XXXXXXXXXXX",
type: "app--XXXXXXXX--XXXXXXX_XXXX",
access: {
admin: "MERCHANT_READ",
storefront: "PUBLIC_READ",
},
},
fields: [
{
value: "[{XXXX_JSON_DATA_XXXXX}]",
key: "XXXX__KEY_NAME__XXXX_json",
},
],
displayName: "App XXXXXXXXXX XXXXX #MSXXXXXXXX",
handle: "app--XXXXXXXXX--XXXX-XXXXX-XXXXXXXX",
id: "gid://shopify/Metaobject/XXXXXXXXX",
type: "app--XXXXXXXXXXX--XXXX__METAOBJ_DEF_TYPE__XXXX",
updatedAt: "2023-09-17T04:49:02Z",
}
"{{ app.metafields.XXXX__METAOBJ_DEF_TYPE__XXXX.XXXX__KEY_NAME__XXXX.value | json }}",
"{{ app.metafields.XXXX__METAOBJ_DEF_TYPE__XXXX.XXXX__KEY_NAME__XXXX}}",
"{{ app.metafields.XXXX__METAOBJ_DEF_TYPE__XXXX.XXXX__KEY_NAME__XXXX.value }}",
"{{ app.metafields.XXXX__METAOBJ_DEF_TYPE__XXXX.XXXX__KEY_NAME__XXXX | json }}"
/**
** Note: I am NOT including the "$app:" prefix
** or the "app-123456" prefix to any of the types above
**/
did you find a solution for this problem? I'm in the same situation and can't find a solution
I ended up using
{{ shop.metafields.app--APP_ID--properties.KEY }}
APP_ID is constant so there shouldn't be any problems. But yes, it's ugly.
We manage multiple custom apps and needed a more automated solution. We haven't found a simpler solution -there might be one-, so this is what we did:
1. Resolve your owned metafield namespace by querying the "currentAppInstallation" with the admin API:
query currentAppInstallation {
currentAppInstallation {
id # This will be used to set a metafield in a later mutation
app {
id # This is your app ID, that is part of the resolved namespace
}
}
}
then, the namespace will be `app--{currentAppInstallation.app.id}--{your-namespace}`.
2. Store it in a metafield in the `currentAppInstallation`:
mutation CreateAppDataMetafield($metafieldsSetInput: [MetafieldsSetInput!]!) {
metafieldsSet(metafields: $metafieldsSetInput) {
metafields {
id
namespace
key
value
}
userErrors {
field
message
}
}
}
variables:
{
"metafieldsSetInput": [
{
"namespace": "{your-namespace}",
"key": "meta_namespace",
"type": "single_line_text_field",
"value": "app--{currentAppInstallation.app.id}--{your-namespace},
"ownerId": {currentAppInstallation.id},
}
]
}
3. Finally, you can access from the liquid template your own metafields on other objects like this:
{% assign resolved_namespace = app.metafields.{your-namespace}.meta_namespace %}
{% assign your_metafield_value = block.settings.product.metafields[resolved_namespace].{your-metafield-key}.value %}
Hope it helps!