Create and manage Shopify pages, blog posts, navigation, and SEO metadata. Workflow: determine content type, generate content, create via API or browser, verify. Use when creating pages, writing blog posts, updating navigation menus, managing redirects, or updating SEO metadata on a Shopify store.
Creates and manages Shopify store content including pages, blog posts, navigation, and SEO metadata via API or browser automation.
npx claudepluginhub jezweb/claude-skillsThis skill inherits all available tools. When active, it can use any tool Claude has access to.
references/content-types.mdCreate and manage Shopify store content — pages, blog posts, navigation menus, and SEO metadata. Produces live content in the store via the Admin API or browser automation.
read_content, write_content scopes (use shopify-setup skill)read_online_store_navigation, write_online_store_navigation scopes| Content Type | API Support | Method |
|---|---|---|
| Pages | Full | GraphQL Admin API |
| Blog posts | Full | GraphQL Admin API |
| Navigation menus | Limited | Browser automation preferred |
| Redirects | Full | REST Admin API |
| SEO metadata | Per-resource | GraphQL on the resource |
| Metaobjects | Full | GraphQL Admin API |
curl -s https://{store}/admin/api/2025-01/graphql.json \
-H "Content-Type: application/json" \
-H "X-Shopify-Access-Token: {token}" \
-d '{
"query": "mutation pageCreate($page: PageCreateInput!) { pageCreate(page: $page) { page { id title handle } userErrors { field message } } }",
"variables": {
"page": {
"title": "About Us",
"handle": "about",
"body": "<h2>Our Story</h2><p>Content here...</p>",
"isPublished": true,
"seo": {
"title": "About Us | Store Name",
"description": "Learn about our story and mission."
}
}
}
}'
Page body accepts HTML. Keep it semantic:
<h2> through <h6> for headings (the page title is <h1>)<p>, <ul>, <ol> for body text<a href="..."> for linksShopify blogs have a two-level structure: Blog (container) > Article (post).
Find or create a blog:
{
blogs(first: 10) {
edges {
node { id title handle }
}
}
}
Most stores have a default blog called "News". Create articles in it:
mutation {
articleCreate(article: {
blogId: "gid://shopify/Blog/123"
title: "New Product Launch"
handle: "new-product-launch"
contentHtml: "<p>We're excited to announce...</p>"
author: { name: "Store Team" }
tags: ["news", "products"]
isPublished: true
publishDate: "2026-02-22T00:00:00Z"
seo: {
title: "New Product Launch | Store Name"
description: "Announcing our latest product range."
}
image: {
src: "https://example.com/blog-image.jpg"
altText: "New product collection"
}
}) {
article { id title handle }
userErrors { field message }
}
}
Navigation menus have limited API support. Use browser automation:
https://{store}.myshopify.com/admin/menusAlternatively, use the GraphQL menuUpdate mutation if the API version supports it:
mutation menuUpdate($id: ID!, $items: [MenuItemInput!]!) {
menuUpdate(id: $id, items: $items) {
menu { id title }
userErrors { field message }
}
}
URL redirects use the REST API:
curl -s https://{store}/admin/api/2025-01/redirects.json \
-H "Content-Type: application/json" \
-H "X-Shopify-Access-Token: {token}" \
-d '{
"redirect": {
"path": "/old-page",
"target": "/new-page"
}
}'
SEO fields are on each resource (product, page, article). Update via the resource's mutation:
mutation {
pageUpdate(page: {
id: "gid://shopify/Page/123"
seo: {
title: "Updated SEO Title"
description: "Updated meta description under 160 chars."
}
}) {
page { id title }
userErrors { field message }
}
}
Query back the content to confirm:
{
pages(first: 10, reverse: true) {
edges {
node { id title handle isPublished createdAt }
}
}
}
Provide the admin URL and the live URL for the user to review:
https://{store}.myshopify.com/admin/pageshttps://{store}.myshopify.com/pages/{handle}For simple content (About, Contact, FAQ), use pages. For structured, repeatable content (team members, testimonials, locations), use metaobjects — they have typed fields and can be queried programmatically.
Every blog post should have:
Use publishDate on articles for scheduled publishing. Pages publish immediately when isPublished: true.
For many pages (e.g. location pages, service pages), use a loop with rate limiting:
for page in pages_data:
create_page(page)
sleep(0.5) # Respect rate limits
references/content-types.md — API endpoints, metaobject patterns, and browser-only operationsUse when working with Payload CMS projects (payload.config.ts, collections, fields, hooks, access control, Payload API). Use when debugging validation errors, security issues, relationship queries, transactions, or hook behavior.