shopify-content
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.
Packaged view
This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.
Install command
npx @skill-hub/cli install jezweb-claude-skills-shopify-content
Repository
Skill path: plugins/shopify/skills/shopify-content
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.
Open repositoryBest for
Primary workflow: Grow & Distribute.
Technical facets: Full Stack, Backend, Tech Writer.
Target audience: everyone.
License: Unknown.
Original source
Catalog source: SkillHub Club.
Repository owner: jezweb.
This is still a mirrored public skill entry. Review the repository before installing into production workflows.
What it helps with
- Install shopify-content into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
- Review https://github.com/jezweb/claude-skills before adding shopify-content to shared team environments
- Use shopify-content for development workflows
Works across
Favorites: 0.
Sub-skills: 0.
Aggregator: No.
Original source / Raw SKILL.md
---
name: shopify-content
description: >
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.
compatibility: claude-code-only
---
# Shopify Content
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.
## Prerequisites
- Admin API access token with `read_content`, `write_content` scopes (use **shopify-setup** skill)
- For navigation: `read_online_store_navigation`, `write_online_store_navigation` scopes
## Workflow
### Step 1: Determine Content Type
| 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 |
### Step 2a: Create Pages
```bash
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:
- Use `<h2>` through `<h6>` for headings (the page title is `<h1>`)
- Use `<p>`, `<ul>`, `<ol>` for body text
- Use `<a href="...">` for links
- Avoid inline styles — the theme handles styling
### Step 2b: Create Blog Posts
Shopify 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:
```graphql
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 }
}
}
```
### Step 2c: Update Navigation Menus
Navigation menus have limited API support. Use browser automation:
1. Navigate to `https://{store}.myshopify.com/admin/menus`
2. Select the menu to edit (typically "Main menu" or "Footer menu")
3. Add, reorder, or remove menu items
4. Save changes
Alternatively, use the GraphQL `menuUpdate` mutation if the API version supports it:
```graphql
mutation menuUpdate($id: ID!, $items: [MenuItemInput!]!) {
menuUpdate(id: $id, items: $items) {
menu { id title }
userErrors { field message }
}
}
```
### Step 2d: Create Redirects
URL redirects use the REST API:
```bash
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"
}
}'
```
### Step 2e: Update SEO Metadata
SEO fields are on each resource (product, page, article). Update via the resource's mutation:
```graphql
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 }
}
}
```
### Step 3: Verify
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:
- Admin: `https://{store}.myshopify.com/admin/pages`
- Live: `https://{store}.myshopify.com/pages/{handle}`
---
## Critical Patterns
### Page vs Metaobject
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.
### Blog SEO
Every blog post should have:
- **SEO title**: under 60 characters, includes primary keyword
- **Meta description**: under 160 characters, compelling summary
- **Handle**: clean URL slug with keywords
- **Image with alt text**: for social sharing and accessibility
### Content Scheduling
Use `publishDate` on articles for scheduled publishing. Pages publish immediately when `isPublished: true`.
### Bulk Content
For many pages (e.g. location pages, service pages), use a loop with rate limiting:
```bash
for page in pages_data:
create_page(page)
sleep(0.5) # Respect rate limits
```
---
## Reference Files
- `references/content-types.md` — API endpoints, metaobject patterns, and browser-only operations
---
## Referenced Files
> The following files are referenced in this skill and included for context.
### references/content-types.md
```markdown
# Shopify Content Types Reference
## API-Managed Content
### Pages
| Operation | Method | Endpoint/Mutation |
|-----------|--------|-------------------|
| List | GraphQL | `{ pages(first: 50) { edges { node { id title } } } }` |
| Create | GraphQL | `pageCreate(page: { ... })` |
| Update | GraphQL | `pageUpdate(page: { id, ... })` |
| Delete | GraphQL | `pageDelete(id: "...")` |
Fields: `title`, `handle`, `body` (HTML), `isPublished`, `seo { title description }`, `templateSuffix`
### Blogs & Articles
| Operation | Method | Endpoint/Mutation |
|-----------|--------|-------------------|
| List blogs | GraphQL | `{ blogs(first: 10) { edges { node { id title } } } }` |
| List articles | GraphQL | `{ articles(first: 50) { edges { node { id title } } } }` |
| Create article | GraphQL | `articleCreate(article: { blogId, ... })` |
| Update article | GraphQL | `articleUpdate(article: { id, ... })` |
| Delete article | GraphQL | `articleDelete(id: "...")` |
Article fields: `blogId`, `title`, `handle`, `contentHtml`, `author { name }`, `tags`, `isPublished`, `publishDate`, `seo`, `image { src altText }`
### Redirects
| Operation | Method | Endpoint |
|-----------|--------|----------|
| List | REST | `GET /admin/api/2025-01/redirects.json` |
| Create | REST | `POST /admin/api/2025-01/redirects.json` |
| Update | REST | `PUT /admin/api/2025-01/redirects/{id}.json` |
| Delete | REST | `DELETE /admin/api/2025-01/redirects/{id}.json` |
Fields: `path` (from), `target` (to)
### Metaobjects
Custom structured content types (e.g. team members, FAQs, locations).
| Operation | Method |
|-----------|--------|
| Define type | `metaobjectDefinitionCreate` |
| Create entry | `metaobjectCreate` |
| Update entry | `metaobjectUpdate` |
| Query entries | `metaobjects(type: "custom_type")` |
## Browser-Only Operations
These have limited or no API support — use browser automation:
| Content | Admin URL | Notes |
|---------|-----------|-------|
| Navigation menus | `/admin/menus` | `menuUpdate` mutation exists but is limited |
| Theme editor | `/admin/themes/current/editor` | Visual layout, no API |
| Store policies | `/admin/settings/legal` | Privacy, terms, refund policies |
| Checkout customisation | `/admin/settings/checkout` | Checkout flow and fields |
| Notification templates | `/admin/settings/notifications` | Email/SMS templates |
## Content Best Practices
### Page Templates
Shopify themes can define custom page templates. Use `templateSuffix` to select one:
```json
{ "templateSuffix": "contact" }
```
This uses `page.contact.liquid` (or `.json` for Online Store 2.0 themes).
### Metaobject vs Metafield
| Use Case | Choose |
|----------|--------|
| Standalone content (FAQ page, team page) | Metaobject |
| Extra data on a product/page | Metafield |
| Repeatable structured entries | Metaobject |
| Single value on a resource | Metafield |
```