Option A — Phase 6: Launch & Publishing Guide
This document is the complete guide for deploying, submitting, and launching AppiFire AI Chat on the Shopify App Store. Prerequisites: Phase 5 complete (billing integrated and tested end-to-end on a dev store).
Phase 6 objective
Section titled “Phase 6 objective”Get the app live on a production server and listed on the Shopify App Store. Know what Shopify reviewers check, what assets you need, and what to do after approval.
PART A: Where to host everything
Section titled “PART A: Where to host everything”| Component | Recommended host | URL | Notes |
|---|---|---|---|
| Backend app (Node/Remix) | Railway or Render | https://ai-chat.appifire.com | Node 20+; one subdomain per app, no path prefix |
| Postgres + pgvector | Neon, Dokploy, Railway, etc. | Your connection string | Use an image with pgvector (e.g. pgvector/pgvector:pg15). If restoring from a SQL dump in databases/, see that folder’s README: extension must be available, embedding column is vector(1536), index is ivfflat. |
| Theme App Extension | Shopify CDN | Served by Shopify after shopify app deploy | No server needed; Shopify hosts extension assets |
| Marketing site | Vercel or Netlify | https://appifire.com | Static site or Next.js; not part of the app server |
Custom domain setup (ai-chat.appifire.com)
Section titled “Custom domain setup (ai-chat.appifire.com)”- On your hosting provider (e.g. Railway → Settings → Custom domain), add
ai-chat.appifire.com(this app’s subdomain). - In your DNS (e.g. Cloudflare, Namecheap), add a CNAME record:
- Name:
ai-chat - Target: the domain your host provides (e.g.
your-ai-chat-app.up.railway.app)
- Name:
- Wait for SSL to provision (usually 1–5 minutes on Railway/Render).
- Verify:
curl https://ai-chat.appifire.com/api/chatshould return your health/chat response (e.g.{"status":"ok"}).
PART B: Deploy backend to Railway (step-by-step)
Section titled “PART B: Deploy backend to Railway (step-by-step)”Railway is the recommended host for its simplicity and Postgres/pgvector support.
Step 1: Create a Railway project
Section titled “Step 1: Create a Railway project”- Go to railway.app and sign in.
- Click New Project → Deploy from GitHub repo.
- Select the
appifire-ai-chatrepo (or the monorepo root — set the Root Directory toappifire-ai-chat/).
Step 2: Add environment variables
Section titled “Step 2: Add environment variables”In Railway → your service → Variables, add:
| Variable | Value |
|---|---|
SHOPIFY_API_KEY | From Partner Dashboard → App → API credentials |
SHOPIFY_API_SECRET | From Partner Dashboard → App → API credentials |
SHOPIFY_APP_URL | https://ai-chat.appifire.com |
SCOPES | write_metaobject_definitions,write_metaobjects,write_products,read_products,read_inventory,read_content,read_themes |
DATABASE_URL | Neon pooled connection string (from Neon dashboard → Connection → Pooled) |
DIRECT_URL | Neon direct connection string (from Neon dashboard → Connection → Direct) |
OPENROUTER_API_KEY | From openrouter.ai → Keys |
NODE_ENV | production |
Step 3: Set the start command
Section titled “Step 3: Set the start command”Railway will auto-detect Node and run npm start. Confirm package.json has:
"start": "react-router-serve ./build/server/index.js","build": "react-router build"Railway runs npm run build then npm start.
Step 4: Run DB migrations on deploy
Section titled “Step 4: Run DB migrations on deploy”Add a Release command in Railway settings (or add to package.json):
"setup": "prisma generate && prisma migrate deploy"Set Release command in Railway to npm run setup. This runs on every deploy, applying pending migrations before the server starts.
Step 5: Deploy
Section titled “Step 5: Deploy”Push to your main branch (or click Deploy in Railway). Watch the deploy logs for:
✓ Prisma migrations applied[react-router] server started
Verify: curl https://ai-chat.appifire.com should return a response (or your app’s root).
PART C: Alternative — Render (step-by-step)
Section titled “PART C: Alternative — Render (step-by-step)”- render.com → New Web Service → connect GitHub repo.
- Root Directory:
appifire-ai-chat. - Build command:
npm install && npm run build. - Start command:
npm run setup && npm start. - Add all environment variables (same as Railway table above).
- Add Custom domain:
ai-chat.appifire.comin Render settings.
PART D: Production checklist before submitting to App Store
Section titled “PART D: Production checklist before submitting to App Store”Complete every item before clicking “Submit for review”.
Code and config
Section titled “Code and config”-
shopify.app.toml:application_url = "https://ai-chat.appifire.com",redirect_urls = ["https://ai-chat.appifire.com/auth/callback"] - All env vars set on host (see table above)
-
npx prisma migrate deploysucceeded on production DB (check Neon → Tables) -
shopify app deployrun — extension and toml pushed to Shopify - App version in dev.shopify.com created with production URLs and set as active
Functional testing on dev store
Section titled “Functional testing on dev store”Install the app fresh on a dev store and test every step:
- OAuth install completes;
shopsrow created in DB - Product sync triggers after install; products visible in
knowledge_chunksandembeddings - Admin settings screen loads; settings save and persist after reload
- Chat widget appears on storefront after adding the block in Theme Editor
- Chat widget sends a product question; correct reply returned from API
- Reply limit works: free shop replies blocked after 50 (test by manually setting count)
- Billing page shows plan and usage; subscribe flow ($10/mo) redirects to Shopify billing confirmation
- App uninstall: shop status set to
uninstalledin DB; sessions deleted - Webhooks delivered: check Partner Dashboard → Apps → your app → Webhooks for delivery logs
Required assets for submission
Section titled “Required assets for submission”- App icon: 1200 × 628 px PNG (used as the App Store card image)
- App icon (small): 512 × 512 px (used inside Shopify Admin)
- Screenshots: at least 3 (recommend 5) at 1280 × 800 px — show: admin settings, storefront widget, billing page, chat in action
- Privacy policy URL: a live, publicly accessible URL (e.g.
https://appifire.com/privacy) — required by Shopify - Support URL or email: e.g.
support@appifire.comorhttps://appifire.com/support - App listing copy:
- Name:
AppiFire AI Chat - Tagline:
AI chatbot that knows your entire product catalog - Short description (≤100 chars): for App Store search results
- Full description (plain text): explain what it does, key features, pricing
- Key benefits (3 bullets): shown on the listing
- Name:
Shopify requirements
Section titled “Shopify requirements”- Scopes in
shopify.app.tomlmatch what the app actually uses (no unused scopes) - App uses App Bridge (
<AppProvider embedded>) for all embedded admin UI - No direct HTTP calls to Shopify API from the frontend (all via backend)
- GDPR webhooks handled (Shopify requires at minimum:
customers/data_request,customers/redact,shop/redact)
PART E: GDPR webhook handlers (required for submission)
Section titled “PART E: GDPR webhook handlers (required for submission)”Shopify requires three mandatory GDPR webhooks. Without them your app will be rejected.
Add to shopify.app.toml:
[[webhooks.subscriptions]]topics = [ "customers/data_request" ]uri = "/webhooks/customers/data_request"
[[webhooks.subscriptions]]topics = [ "customers/redact" ]uri = "/webhooks/customers/redact"
[[webhooks.subscriptions]]topics = [ "shop/redact" ]uri = "/webhooks/shop/redact"Create stub handlers (required to return 200; full implementation required if you store customer PII):
app/routes/webhooks.customers.data_request.jsx
import { authenticate } from "../shopify.server";export const action = async ({ request }) => { await authenticate.webhook(request); // TODO: if you store customer PII, return the data here return new Response();};app/routes/webhooks.customers.redact.jsx
import { authenticate } from "../shopify.server";export const action = async ({ request }) => { await authenticate.webhook(request); // TODO: delete any customer PII stored (chat messages, visitor IDs) return new Response();};app/routes/webhooks.shop.redact.jsx
import { authenticate } from "../shopify.server";import db from "../db.server";export const action = async ({ request }) => { const { shop } = await authenticate.webhook(request); // When a shop requests data deletion (e.g. after uninstall + 48h), delete all their data const dbShop = await db.shop.findFirst({ where: { shopDomain: shop } }); if (dbShop) { await db.shop.delete({ where: { id: dbShop.id } }); // cascade deletes all related rows } return new Response();};PART F: Shopify App Store submission process
Section titled “PART F: Shopify App Store submission process”Where to submit
Section titled “Where to submit”- Open Partner Dashboard → Apps → AppiFire AI Chat.
- In the left sidebar, click Distribution.
- Click Shopify App Store.
- Fill in the App listing form (name, description, screenshots, pricing, support info).
- Click Submit app.
Review timeline
Section titled “Review timeline”- Shopify reviewers typically respond within 5–14 business days.
- You will receive an email with approval or a list of issues to fix.
- After fixing issues, you re-submit; subsequent reviews are usually faster (2–5 days).
What Shopify reviewers test
Section titled “What Shopify reviewers test”They will install your app on a test store and verify:
- App installs without errors (OAuth completes, no 500 errors).
- The embedded admin UI loads inside Shopify Admin (no white screen, no auth loop).
- The app does what the listing says (chat widget appears, responds to questions).
- All stated scopes are actually used.
- Billing works (subscription flow doesn’t crash; test mode accepted during review).
- Uninstall works cleanly (no orphaned data issues, redirect errors).
- Privacy policy URL is live and accessible.
- GDPR webhooks are registered.
Test instructions to write for reviewers
Section titled “Test instructions to write for reviewers”Include these in the “Test instructions” field on the submission form:
1. Install the app on your development store.2. After install, the app automatically syncs products. Wait 30 seconds.3. Open the app (Settings page) — adjust widget title and colour, click Save.4. Go to Online Store → Themes → Customize. Add the "AppiFire Chat Widget" block to any section. Save.5. Open the storefront. The chat bubble should appear bottom-right.6. Click the bubble and type: "Do you have any [product from the store]?" The widget should return a relevant AI reply.7. Back in the admin, go to Billing. The usage counter should show 1 reply used.8. To test billing: click "Subscribe for $10/mo". You will be redirected to Shopify billing — use a test store charge.9. Uninstall the app. The shop's status should be set to "uninstalled" (no data errors).
Test store credentials: [provide login URL and password]Common rejection reasons (and fixes)
Section titled “Common rejection reasons (and fixes)”| Rejection reason | Fix |
|---|---|
| ”App doesn’t install correctly” | Check OAuth routes; ensure auth/callback returns 200 and redirects to app |
| ”Missing privacy policy” | Add a live privacy policy page at https://appifire.com/privacy |
| ”Scopes too broad” | Remove any scope in shopify.app.toml that the app doesn’t actively use |
| ”App Bridge not used correctly” | Ensure all admin pages use <AppProvider embedded> and authenticate.admin() |
| ”GDPR webhooks missing” | Add all three GDPR webhook routes (see Part E) |
| “Extension not working in Dawn theme” | Test extension in the Dawn theme specifically (Shopify’s default) |
| “Billing not implemented” | Test charge flow in test mode; ensure plan upgrades work |
PART G: Post-launch
Section titled “PART G: Post-launch”Monitoring
Section titled “Monitoring”- Webhook failures: Partner Dashboard → Apps → Webhooks → check for failed deliveries.
- Error logging: add Sentry (
npm install @sentry/node) and initialise inentry.server.jsx. Catches unhandled errors in production. - Neon DB: monitor connection count and query latency in Neon dashboard. Upgrade from free tier when needed.
App Store ranking
Section titled “App Store ranking”- Respond to every review within 48 hours (even 1-star reviews). Shopify ranks apps partly by response rate.
- Ask satisfied merchants (via follow-up email or in-app nudge) to leave a review.
- Keep the listing description updated when you add major features.
Iterating after launch
Section titled “Iterating after launch”- Use the
openrouter_callsandchat_messagestables to see what customers are asking. Improve your chunking and prompts based on real questions. - Add FAQ/policy documents as knowledge sources (extend
knowledge_sourcesingestion). - Consider adding email notifications (e.g. daily summary of replies used) to keep merchants engaged.
Full launch checklist
Section titled “Full launch checklist”Hosting & deploy
Section titled “Hosting & deploy”- Backend deployed to Railway/Render at
https://ai-chat.appifire.com - Custom domain SSL active;
curl https://ai-chat.appifire.com/api/chatreturns 200 - All env vars set on host
- Production DB migrations applied
-
shopify app deployrun; extension and config live in Shopify
Functional testing
Section titled “Functional testing”- Fresh install on dev store works end-to-end
- Product sync, settings, widget, chat, billing all tested
- Uninstall tested
Submission assets
Section titled “Submission assets”- App icon 1200×628 px
- App icon 512×512 px
- 3–5 screenshots at 1280×800 px
- Privacy policy URL live
- Support URL or email confirmed
- App listing copy written (name, tagline, description)
- Pricing section configured in Partner Dashboard listing
Shopify requirements
Section titled “Shopify requirements”- GDPR webhooks registered and handlers responding 200
- Unused scopes removed from
shopify.app.toml - Test instructions written for reviewers
- App Bridge used correctly in all admin routes
Post-launch
Section titled “Post-launch”- Sentry (or equivalent) error tracking configured
- Webhook delivery monitored
- Review response process in place