/shopify-json-ld
Use when adding structured data / JSON-LD / schema markup to a Shopify store: recipe, FAQ, Article/BlogPosting, CollectionPage, AboutPage, or Organization schema; chasing Google rich-results / rich-snippet eligibility; debugging a Search Console "Invalid object type" or "missing
Claude Code
$ npx -y skills add kgelster/awesome-ecom-skills --skill shopify-json-ld --agent claude-code
Codex
$ npx skills add kgelster/awesome-ecom-skills --skill shopify-json-ld -a codex -y
Cursor
$ npx skills add kgelster/awesome-ecom-skills --skill shopify-json-ld -a cursor -y
Gemini CLI
$ npx skills add kgelster/awesome-ecom-skills --skill shopify-json-ld -a gemini-cli -y
GitHub Copilot
$ npx skills add kgelster/awesome-ecom-skills --skill shopify-json-ld -a github-copilot -y
OpenCode
$ npx skills add kgelster/awesome-ecom-skills --skill shopify-json-ld -a opencode -y
Windsurf
$ npx skills add kgelster/awesome-ecom-skills --skill shopify-json-ld -a windsurf -y
SKILL.md
shopify-json-ld.SKILL.mdname: shopify-json-ld
description: >-
Use when adding structured data / JSON-LD / schema markup to a Shopify store:
recipe, FAQ, Article/BlogPosting, CollectionPage, AboutPage, or Organization
schema; chasing Google rich-results / rich-snippet eligibility; debugging a
Search Console "Invalid object type" or "missing field" schema error; or a
request like "add schema to my store", "add recipe schema", or "why isn't my
product showing rich results". This skill adds SUPPLEMENTAL JSON-LD the theme
cannot emit dynamically, stored in a metafield and rendered by one Liquid
snippet. Not for meta titles, meta descriptions, canonical tags, or Open Graph
(use shopify-seo-metadata for those).
compatibility: >-
Requires Shopify Admin API access (custom-app token or Shopify CLI 3.x) plus
theme/Liquid edit access to add one render snippet. GraphQL written against
Admin API 2025-07.
Shopify JSON-LD
Adds **supplemental** structured data to a Shopify store: the schema types the theme can't generate on its own (Recipe, FAQPage, richer Article/Collection nodes), stored as JSON-LD in a per-entity metafield and rendered through a single Liquid snippet. The governing principle: **you add what's missing, you never duplicate what the theme already emits.** For meta tags, descriptions, and Open Graph (a different job), use the sibling skill **shopify-seo-metadata**.
Store access
**Lane A: custom-app token (scriptable).** In Shopify admin: Settings → Apps and sales channels → Develop apps → create an app → grant this skill's minimum scopes, then install and copy the Admin API access token. Export it; never write it to a committed file:
export SHOPIFY_STORE="your-store.myshopify.com"
export SHOPIFY_ACCESS_TOKEN="<your Admin API access token>" # env only, not on disk
Minimum scopes: `read_products`, `write_products`, `read_content`, `write_content`. There is no standalone metafield scope; metafield access is governed by the owning resource's scope (products → `write_products`, pages/articles → `write_content`). Rendering the snippet needs **theme edit access** (theme editor or the theme's Git repo), which is separate from the API. Sanity-check the token:
curl -s "https://$SHOPIFY_STORE/admin/api/2025-07/graphql.json" \
-H "X-Shopify-Access-Token: $SHOPIFY_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"query":"{ shop { name } }"}'**Lane B: Shopify CLI OAuth (no stored token).** `shopify store auth --store $SHOPIFY_STORE --scopes read_products,write_products,read_content,write_content` then `shopify store execute`. Good for token-less stores where the owner logs in.
**Toolkit preflight.** Lane B rides on the Shopify CLI: run `shopify version` first and install it if missing. For the full Admin GraphQL schema and validated execution, pair this skill with Shopify's official AI toolkit plugin. In Claude Code, check `claude plugin list`; if it isn't there:
claude plugin marketplace add Shopify/Shopify-AI-Toolkit
claude plugin install shopify-plugin@shopify-ai-toolkit
Recommended, not required: Lane A needs only curl and a token. The toolkit gives your agent the API; this skill gives it the playbook.
Supplemental-only doctrine: audit before you generate
Modern Shopify themes already emit Product schema on PDPs (price, variants, availability, and, with a review app like Judge.me, Yotpo, or Stamped, `aggregateRating`), plus Organization/WebSite sitewide and often Article/BreadcrumbList. **Duplicating any of it creates conflicting nodes that degrade eligibility, not improve it.**
So the first move is always read-only: fetch the homepage, a PDP, a collection, and a blog post, and extract every `<script type="application/ld+json">` block.
curl -s "https://$SHOPIFY_STORE/products/<some-handle>" \
| grep -o '<script type="application/ld+json">[^<]*' | head
Whatever the theme already covers, you do **not** touch. Supplemental schema is a *separate* type on the same page (a FAQPage or Recipe node alongside the theme's Product node), never a second Product node. If the theme's Product schema is broken or missing, fix the theme. Don't paper over it with a duplicate.
The metafield + snippet pattern
Store the JSON-LD in a metafield and render it verbatim. Nothing transforms the value at render time, so the stored string must already be valid JSON-LD.
1. **Define the metafield** (Settings → Custom Data → the entity type → Add definition): namespace `custom`, key `json`, type `multi_line_text_field`. Create it for each entity type you'll populate (Products, Collections, Pages, Articles).
2. **Add one render snippet** to `theme.liquid`, before `</head>`:
{%- if request.page_type == 'product' and product.metafields.custom.json != blank -%}
<script type="application/ld+json">{{ product.metafields.custom.json }}</script>
{%- elsif request.page_type == 'collection' and collection.metafields.custom.json != blank -%}
<script type="application/ld+json">{{ collection.metafields.custom.json }}</script>
{%- elsif request.page_type == 'page' and page.metafields.custom.json != blank -%}
<script type="application/ld+json">{{ page.metafields.custom.json }}</script>
{%- elsif request.page_type == 'article' and article.metafields.custom.json != blank -%}
<script type="application/ld+json">{{ article.metafields.custom.json }}</script>
{%- endif -%}3. **Write the value with `metafieldsSet`** (GraphQL). It upserts by namespace/key, so it updates an existing metafield instead of duplicating it: this sidesteps the classic REST trap of POSTing a second metafield when one already exists. Store the JSON compact (`JSON.stringify(obj)`, no pretty spacing). Preview the target count before a bulk write; a count far above expectation means stop and re-scope. Full pipeline and per-entity prompts: [references/pipeline-and-prompts.md](references/pipeline-and-prompts.md).
Two schema
Read more
name: shopify-json-ld description: >- Use when adding structured data / JSON-LD / schema markup to a Shopify store: recipe, FAQ, Article/BlogPosting, CollectionPage, AboutPage, or Organization schema; chasing Google rich-results / rich-snippet eligibility; debugging a Search Console "Invalid object type" or "missing field" schema error; or a request like "add schema to my store", "add recipe schema", or "why isn't my product showing rich results". This skill adds SUPPLEMENTAL JSON-LD the theme cannot emit dynamically, stored in a metafield and rendered by one Liquid snippet. Not for meta titles, meta descriptions, canonical tags, or Open Graph (use shopify-seo-metadata for those). compatibility: >- Requires Shopify Admin API access (custom-app token or Shopify CLI 3.x) plus theme/Liquid edit access to add one render snippet. GraphQL written against Admin API 2025-07.
Shopify JSON-LD
Adds **supplemental** structured data to a Shopify store: the schema types the theme can't generate on its own (Recipe, FAQPage, richer Article/Collection nodes), stored as JSON-LD in a per-entity metafield and rendered through a single Liquid snippet. The governing principle: **you add what's missing, you never duplicate what the theme already emits.** For meta tags, descriptions, and Open Graph (a different job), use the sibling skill **shopify-seo-metadata**.
Store access
**Lane A: custom-app token (scriptable).** In Shopify admin: Settings → Apps and sales channels → Develop apps → create an app → grant this skill's minimum scopes, then install and copy the Admin API access token. Export it; never write it to a committed file:
export SHOPIFY_STORE="your-store.myshopify.com" export SHOPIFY_ACCESS_TOKEN="<your Admin API access token>" # env only, not on disk
Minimum scopes: `read_products`, `write_products`, `read_content`, `write_content`. There is no standalone metafield scope; metafield access is governed by the owning resource's scope (products → `write_products`, pages/articles → `write_content`). Rendering the snippet needs **theme edit access** (theme editor or the theme's Git repo), which is separate from the API. Sanity-check the token:
curl -s "https://$SHOPIFY_STORE/admin/api/2025-07/graphql.json" \
-H "X-Shopify-Access-Token: $SHOPIFY_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"query":"{ shop { name } }"}'**Lane B: Shopify CLI OAuth (no stored token).** `shopify store auth --store $SHOPIFY_STORE --scopes read_products,write_products,read_content,write_content` then `shopify store execute`. Good for token-less stores where the owner logs in.
**Toolkit preflight.** Lane B rides on the Shopify CLI: run `shopify version` first and install it if missing. For the full Admin GraphQL schema and validated execution, pair this skill with Shopify's official AI toolkit plugin. In Claude Code, check `claude plugin list`; if it isn't there:
claude plugin marketplace add Shopify/Shopify-AI-Toolkit claude plugin install shopify-plugin@shopify-ai-toolkit
Recommended, not required: Lane A needs only curl and a token. The toolkit gives your agent the API; this skill gives it the playbook.
Supplemental-only doctrine: audit before you generate
Modern Shopify themes already emit Product schema on PDPs (price, variants, availability, and, with a review app like Judge.me, Yotpo, or Stamped, `aggregateRating`), plus Organization/WebSite sitewide and often Article/BreadcrumbList. **Duplicating any of it creates conflicting nodes that degrade eligibility, not improve it.**
So the first move is always read-only: fetch the homepage, a PDP, a collection, and a blog post, and extract every `<script type="application/ld+json">` block.
curl -s "https://$SHOPIFY_STORE/products/<some-handle>" \ | grep -o '<script type="application/ld+json">[^<]*' | head
Whatever the theme already covers, you do **not** touch. Supplemental schema is a *separate* type on the same page (a FAQPage or Recipe node alongside the theme's Product node), never a second Product node. If the theme's Product schema is broken or missing, fix the theme. Don't paper over it with a duplicate.
The metafield + snippet pattern
Store the JSON-LD in a metafield and render it verbatim. Nothing transforms the value at render time, so the stored string must already be valid JSON-LD.
1. **Define the metafield** (Settings → Custom Data → the entity type → Add definition): namespace `custom`, key `json`, type `multi_line_text_field`. Create it for each entity type you'll populate (Products, Collections, Pages, Articles).
2. **Add one render snippet** to `theme.liquid`, before `</head>`:
{%- if request.page_type == 'product' and product.metafields.custom.json != blank -%}
<script type="application/ld+json">{{ product.metafields.custom.json }}</script>
{%- elsif request.page_type == 'collection' and collection.metafields.custom.json != blank -%}
<script type="application/ld+json">{{ collection.metafields.custom.json }}</script>
{%- elsif request.page_type == 'page' and page.metafields.custom.json != blank -%}
<script type="application/ld+json">{{ page.metafields.custom.json }}</script>
{%- elsif request.page_type == 'article' and article.metafields.custom.json != blank -%}
<script type="application/ld+json">{{ article.metafields.custom.json }}</script>
{%- endif -%}3. **Write the value with `metafieldsSet`** (GraphQL). It upserts by namespace/key, so it updates an existing metafield instead of duplicating it: this sidesteps the classic REST trap of POSTing a second metafield when one already exists. Store the JSON compact (`JSON.stringify(obj)`, no pretty spacing). Preview the target count before a bulk write; a count far above expectation means stop and re-scope. Full pipeline and per-entity prompts: [references/pipeline-and-prompts.md](references/pipeline-and-prompts.md).
Two schema
Shopify's plugin gives your agent the API. This gives it the playbook. Shopify's official AI toolkit gives your agent the Admin API: schema, mutations, reference.
Other skills on ecom.
More skills from other plugins.
browser-use
Direct browser control via CDP for web interaction: automation, scraping, testing, screenshots, and site/app work. Also covers…
agent-browser
Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling…
Questions about shopify-json-ld.
- Which coding agents can use shopify-json-ld?
- shopify-json-ld installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.

