From shopify-pack
Sets up local Shopify app development with Shopify CLI scaffolding, ngrok tunneling for webhooks, hot reload, and Vitest testing.
npx claudepluginhub jeremylongshore/claude-code-plugins-plus-skills --plugin shopify-packThis skill is limited to using the following tools:
Set up a fast, reproducible local development workflow using Shopify CLI, ngrok tunneling for webhooks, and Vitest for testing against the Shopify API.
Guides Next.js Cache Components and Partial Prerendering (PPR) with cacheComponents enabled. Implements 'use cache', cacheLife(), cacheTag(), revalidateTag(), static/dynamic optimization, and cache debugging.
Guides building MCP servers enabling LLMs to interact with external services via tools. Covers best practices, TypeScript/Node (MCP SDK), Python (FastMCP).
Generates original PNG/PDF visual art via design philosophy manifestos for posters, graphics, and static designs on user request.
Set up a fast, reproducible local development workflow using Shopify CLI, ngrok tunneling for webhooks, and Vitest for testing against the Shopify API.
shopify-install-auth setupnpm install -g @shopify/cli)# Create a new Remix-based Shopify app (recommended)
shopify app init
# Or scaffold manually
mkdir my-shopify-app && cd my-shopify-app
npm init -y
npm install @shopify/shopify-api @shopify/shopify-app-remix \
@shopify/app-bridge-react @remix-run/node @remix-run/react
my-shopify-app/
├── app/
│ ├── routes/
│ │ ├── app._index.tsx # Main app page
│ │ ├── app.products.tsx # Products management
│ │ ├── auth.$.tsx # OAuth callback
│ │ └── webhooks.tsx # Webhook handler
│ ├── shopify.server.ts # Shopify API client setup
│ └── root.tsx
├── extensions/ # Theme app extensions
├── shopify.app.toml # App configuration
├── .env # Local secrets (git-ignored)
├── .env.example # Template for team
└── package.json
# shopify.app.toml — central app configuration
name = "My App"
client_id = "your_api_key_here"
[access_scopes]
scopes = "read_products,write_products,read_orders"
[auth]
redirect_urls = [
"https://localhost/auth/callback",
"https://localhost/auth/shopify/callback",
]
[webhooks]
api_version = "2024-10"
[webhooks.subscriptions]
# Mandatory GDPR webhooks
[[webhooks.subscriptions]]
topics = ["customers/data_request"]
uri = "/webhooks"
[[webhooks.subscriptions]]
topics = ["customers/redact"]
uri = "/webhooks"
[[webhooks.subscriptions]]
topics = ["shop/redact"]
uri = "/webhooks"
# Shopify CLI handles ngrok tunnel + OAuth automatically
shopify app dev
# This will:
# 1. Start your app on localhost:3000
# 2. Create an ngrok tunnel
# 3. Update your app URLs in Partner Dashboard
# 4. Open your app in the dev store admin
# 5. Hot reload on file changes
// tests/shopify-client.test.ts
import { describe, it, expect, vi, beforeEach } from "vitest";
// Mock the Shopify API client
vi.mock("@shopify/shopify-api", () => ({
shopifyApi: vi.fn(() => ({
clients: {
Graphql: vi.fn().mockImplementation(() => ({
request: vi.fn().mockResolvedValue({
data: {
products: {
edges: [
{ node: { id: "gid://shopify/Product/1", title: "Test Product" } },
],
},
},
}),
})),
},
session: {
customAppSession: vi.fn(() => ({ shop: "test.myshopify.com" })),
},
})),
}));
describe("Shopify Integration", () => {
it("should fetch products", async () => {
// Test your product-fetching logic here
});
it("should handle GraphQL errors", async () => {
// Test error handling
});
});
{
"scripts": {
"dev": "shopify app dev",
"build": "remix vite:build",
"test": "vitest",
"test:watch": "vitest --watch",
"lint": "eslint app/",
"shopify": "shopify",
"deploy": "shopify app deploy"
}
}
# Open the Shopify GraphiQL explorer for your store
# Navigate to: https://your-store.myshopify.com/admin/api/2024-10/graphql.json
# Use the Shopify Admin GraphiQL app (install from admin)
# Or use curl to test queries directly:
curl -X POST \
"https://your-store.myshopify.com/admin/api/2024-10/graphql.json" \
-H "Content-Type: application/json" \
-H "X-Shopify-Access-Token: shpat_xxx" \
-d '{"query": "{ shop { name } }"}'
| Error | Cause | Solution |
|---|---|---|
Could not find a Shopify partner organization | CLI not logged in | Run shopify auth login |
Port 3000 already in use | Another process on port | Kill process or use --port 3001 |
Tunnel connection failed | ngrok issues | Check ngrok status or use --tunnel-url |
App not installed on store | First time setup | Open the URL CLI provides, accept install |
SHOPIFY_API_KEY not set | Missing .env | Copy from .env.example and fill in values |
// Enable verbose request logging in development
import { LogSeverity } from "@shopify/shopify-api";
const shopify = shopifyApi({
// ... other config
logger: {
level: LogSeverity.Debug, // Logs all requests/responses
httpRequests: true,
timestamps: true,
},
});
// scripts/seed-dev-store.ts — create test products
async function seedStore(client: any) {
const products = [
{ title: "Test Widget", productType: "Widget", vendor: "Dev" },
{ title: "Test Gadget", productType: "Gadget", vendor: "Dev" },
];
for (const product of products) {
await client.request(`
mutation { productCreate(product: {
title: "${product.title}",
productType: "${product.productType}",
vendor: "${product.vendor}"
}) {
product { id title }
userErrors { field message }
}}
`);
}
}
See shopify-sdk-patterns for production-ready code patterns.