Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Create and manage Shopify pages, blog posts, navigation menus, redirects, and SEO metadata via the Admin API or browser automation. Use whenever the user wants to add a page to a Shopify store, write a Shopify blog post, update the storefront navigation, manage redirects, or tune SEO metadata on a Shopify site.
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-07 | ✗→✓ | ▲ Improved | 32% | 0% |
| case-01 | ✗→✓ | ▲ Improved | 151% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 48% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 117% | 0% |
| case-12 | ✗→✓ | ▲ Improved | 40% | 0% |
Create 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 |
bashcurl -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:
graphql{ blogs(first: 10) { edges { node { id title handle } } } }
Most stores have a default blog called "News". Create articles in it:
graphqlmutation { 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:
graphqlmutation menuUpdate($id: ID!, $items: [MenuItemInput!]!) { menuUpdate(id: $id, items: $items) { menu { id title } userErrors { field message } } }
URL redirects use the REST API:
bashcurl -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:
graphqlmutation { 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:
graphql{ 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:
bashfor page in pages_data: create_page(page) sleep(0.5) # Respect rate limits
references/content-types.md — API endpoints, metaobject patterns, and browser-only operationsOther measured skills in the registry, with their headline benchmark lift.