AnswerReady
A Shopify app that audits and fixes AI-search schema — without touching the theme.
- FUNCTION
- SEO / AI-search schema audit + repair
- METHOD
- Non-destructive JSON-LD overlay
- STATUS
- Phase 1 complete · in build
- ROLE
- Solo · strategy → ops
01The problem
Shopify themes emit inconsistent or incomplete JSON-LD — missing product identifiers, no shipping or return-policy schema, no review aggregation. That quietly cuts merchant visibility in Google rich results and AI shopping engines like ChatGPT, Gemini, and Perplexity.
Existing tools either rewrite theme files — hard to uninstall, prone to conflicts — or check against assumed best practices instead of the actual published Google / OpenAI specs. Merchants get no per-product diagnosis and no way to detect a regression after a theme update.
02Approach
Rather than editing theme Liquid, the app injects schema through a theme app-extension app-embed block — server-side JSON-LD added at the platform layer, with zero residual code on uninstall by construction.
Before the extension ever enables, it reads the live rendered page, shows a diff of current vs. proposed markup, and waits for explicit approval. Deliberately no Asset API, no theme-file writes, no auto-applied changes.
The uninstall-clean architecture and the approval queue are the product — the trust argument against every incumbent that earns one-star "it overwrote my theme" reviews.
03How it works
- Admin GraphQL fetches store + product data — names, variants, GTINs, review metafields, images — read-only,
read_productsscope only. - A live storefront probe fetches
robots.txt,/llms.txt,/agents.mdin parallel; returns explicit "n/a" if the storefront is password-protected. - The ruleset — 5 categories, 20+ weighted pure functions — scores readiness 0–100 against sourced specs; each check carries the URL of the standard it measures.
- A monitor crawler fetches rendered HTML, extracts every JSON-LD block, and validates structure — catching theme conflicts the Admin-data audit can't see.
- Each run is persisted per shop for score trending; the dashboard shows the delta and the top-3 fixes. A
products/updatewebhook triggers a re-audit. - [Planned] The extension emits corrected JSON-LD; a conflict detector suppresses duplicate markup; a re-scan confirms the fix — closing the detect → diagnose → overlay → verify loop.
04Capabilities
- 5-category readiness score, spec-sourced per check
- Per-product coverage: GTINs, copy, images, reviews
- Live probe: AI-crawler access, llms.txt, agents.md
- JSON-LD crawler validates real rendered markup
- Score trend across runs + webhook re-audit
- Theme-extension schema overlay PLANNED
- Preview diff before enabling PLANNED
- Scheduled scans + diff alerts PLANNED
05Stack
- LANGUAGE
- TypeScript (strict) · Node ≥ 20.19
- FRONTEND
- React 18 · React Router v7 · Polaris web components · App Bridge React
- BACKEND / DATA
- RR server loaders/actions · Prisma 6 · SQLite (dev) → Postgres · Admin GraphQL 2026-07
- PLATFORM
- Shopify embedded app (OAuth + session tokens) · webhooks: products/update, app/uninstalled, scopes_update
- INFRA / DEPLOY
- Dockerfile · target Fly.io · pnpm workspaces · Vite 6 · Vitest 3 · GitHub Actions CI
06Engineering notes
-
Ruleset is pure functions.
AuditContextin,CheckOutcomeout. All network I/O sits strictly upstream in the loader, so the 370-line ruleset runs under Vitest with no mocks. The regression surface here is high — the purity constraint was a deliberate structural choice. -
Honest "na", never a silent pass. Channel checks return an explicit
nawhen the storefront is unreachable or password-protected — not a false fail, not a quiet pass. The score's credibility rests on never poisoning it with unmeasurable signals. -
The JSON-LD a crawler actually sees. The validator walks
@graphcontainers, nested arrays, and mixed@typearrays extracted from raw HTML — the real shape AI crawlers hit, not the clean object the Admin API returns. This catches@graph-wrapped theme markup a naive "has Product schema?" check misses. -
[Phase 2] Conflict detection. Once the extension enables, the monitor must identify duplicate schema by
@type, determine the source — theme vs. another app — and suppress it without breaking either emitter. The hardest part of staying uninstall-clean.
07Status
Working: audit engine (score + per-category + sourced todos), live channel probe, JSON-LD crawler + validator, per-shop run persistence + trending, dashboard v1, monitor UI, products/update webhook, onboarding & empty states.
Not yet built: theme app extension (the fix mechanism), conflict detection, preview-diff UI, scheduled scans, diff alerts, production Postgres + Fly.io, pg-boss queue, billing + plan gating, GDPR webhooks, App Store listing.
08What's next
- Theme app extension — app-embed block, conflict detection, uninstall-clean by construction — plus the preview-diff UI and the re-scan verify loop.
- Production infra: Postgres on Fly.io, a pg-boss job queue, scheduled scans, and diff-based email alerts ("a theme update removed Product schema on 14 pages").