[{"data":1,"prerenderedAt":130},["ShallowReactive",2],{"work-shopify-ai-copilot":3},{"id":4,"title":5,"body":6,"category":92,"challenge":93,"codeSnippet":94,"description":98,"extension":99,"featured":100,"finalScreenshot":101,"gridOrder":102,"isDemo":100,"isDemoURL":85,"liveUrl":102,"meta":103,"mockupImage":104,"navigation":105,"nextProject":106,"order":86,"path":109,"results":110,"schneiderFeatured":100,"schneiderOrder":102,"seo":111,"solution":112,"stem":113,"subtitle":114,"tags":115,"techStack":120,"thumbnail":127,"thumbnailVideo":102,"year":128,"__hash__":129},"works/works/shopify-ai-copilot.md","Scribe",{"type":7,"value":8,"toc":84},"minimark",[9,14,18,22,25,37,43,49,55,59,65,71,77,81],[10,11,13],"h2",{"id":12},"the-problem","The Problem",[15,16,17],"p",{},"Shopify merchants — especially those scaling to hundreds or thousands of products — face a content bottleneck. Each product needs a compelling description, SEO-optimized title and meta description, and often variant-specific copy. Generic AI tools produce generic output because they lack store context: what's the brand voice? What are the top-selling products? What keywords drive traffic?",[10,19,21],{"id":20},"architecture","Architecture",[15,23,24],{},"The app is built as a standard Shopify embedded app using Remix and App Bridge:",[15,26,27,31,32,36],{},[28,29,30],"strong",{},"Authentication & Session"," — OAuth flow via ",[33,34,35],"code",{},"@shopify/shopify-app-remix"," with session tokens stored in PostgreSQL via Prisma. Redis handles rate limiting and response caching.",[15,38,39,42],{},[28,40,41],{},"Context Engine"," — Before any generation, the app pulls relevant context: the target product's full data, similar products in the same collection, the store's best-performing listings (by conversion rate), and any brand voice settings the merchant has configured.",[15,44,45,48],{},[28,46,47],{},"Streaming Generation"," — Claude responses stream directly to the frontend via Server-Sent Events. The Polaris UI renders tokens as they arrive, giving merchants instant feedback. They can accept, edit, or regenerate with modified instructions.",[15,50,51,54],{},[28,52,53],{},"Batch Operations"," — For catalog-wide SEO optimization, the app queues generation jobs that process products in parallel, respecting both Shopify API rate limits and Claude API throughput.",[10,56,58],{"id":57},"key-technical-decisions","Key Technical Decisions",[15,60,61,64],{},[28,62,63],{},"Why streaming SSE over WebSockets?"," Shopify's App Bridge iframe environment has restrictions on WebSocket connections. SSE works reliably within the iframe context and is simpler to implement for the unidirectional data flow of AI generation.",[15,66,67,70],{},[28,68,69],{},"Why build context from Shopify data instead of RAG?"," The merchant's product catalog is structured data that fits cleanly into a prompt context window. Vector search adds latency and complexity for data that's already well-organized in Shopify's GraphQL API.",[15,72,73,76],{},[28,74,75],{},"Why Redis for caching?"," Similar products often need similar metadata. Caching generation results by product type + collection reduces API costs by ~40% and gives instant results for common patterns.",[10,78,80],{"id":79},"outcome","Outcome",[15,82,83],{},"Merchants using Scribe complete product listings 6x faster on average. The SEO module drove a measurable increase in organic traffic within the first month for pilot stores, primarily from improved meta description coverage (most merchants had left these blank before).",{"title":85,"searchDepth":86,"depth":86,"links":87},"",2,[88,89,90,91],{"id":12,"depth":86,"text":13},{"id":20,"depth":86,"text":21},{"id":57,"depth":86,"text":58},{"id":79,"depth":86,"text":80},"Shopify App","Merchants spend hours writing product descriptions, optimizing SEO metadata, and crafting customer emails. Existing AI writing tools require context-switching out of Shopify and don't understand the merchant's catalog, brand voice, or customer base.",{"language":95,"filename":96,"code":97},"typescript","app/routes/api.generate.tsx","export async function action({ request }: ActionFunctionArgs) {\n  const { admin, session } = await authenticate.admin(request)\n  const { productId, prompt, type } = await request.json()\n\n  // Fetch product context from Shopify\n  const { product } = await admin.graphql(`\n    query GetProduct($id: ID!) {\n      product(id: $id) {\n        title\n        vendor\n        productType\n        tags\n        variants(first: 10) {\n          nodes { title price }\n        }\n      }\n    }\n  `, { variables: { id: productId } })\n\n  const stream = await anthropic.messages.stream({\n    model: 'claude-sonnet-4-20250514',\n    max_tokens: 1024,\n    system: buildMerchantContext(session.shop, product),\n    messages: [{ role: 'user', content: prompt }],\n  })\n\n  return new Response(stream.toReadableStream(), {\n    headers: {\n      'Content-Type': 'text/event-stream',\n      'Cache-Control': 'no-cache',\n    },\n  })\n}\n","An embedded Shopify app that gives merchants an AI content engine for product descriptions, SEO optimization, and customer communication — all within the Shopify admin.","md",false,"/images/projects/shopify-ai-copilot-final.jpg",null,{},"/images/projects/shopify-ai-copilot-mockup.jpg",true,{"title":107,"slug":108},"LiquidGuard SAST","liquidguard-sast","/works/shopify-ai-copilot","Average product listing time reduced from 25 minutes to 4 minutes. SEO metadata completion rate increased from 35% to 98% across merchant catalogs.",{"title":5,"description":98},"Built a Remix-based embedded Shopify app that deeply integrates with the admin. Scribe reads product data, collection context, and store analytics to generate contextually aware content with streaming responses powered by Claude.","works/shopify-ai-copilot","AI Content Engine for Shopify Merchants",[116,117,92,118,119],"Remix","Claude","Streaming","Polaris",[116,121,119,122,123,124,125,126],"Shopify App Bridge","Claude API","Prisma","PostgreSQL","Redis","Streaming SSE","/images/projects/shopify-ai-copilot.jpg","2026","mGnspdNJ-9QlqK09I8Cm0ixH3I4f8uwQWA0SrtYGC-E",1773700381404]