Skip to content

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).


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.


ComponentRecommended hostURLNotes
Backend app (Node/Remix)Railway or Renderhttps://ai-chat.appifire.comNode 20+; one subdomain per app, no path prefix
Postgres + pgvectorNeon, Dokploy, Railway, etc.Your connection stringUse 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 ExtensionShopify CDNServed by Shopify after shopify app deployNo server needed; Shopify hosts extension assets
Marketing siteVercel or Netlifyhttps://appifire.comStatic 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)”
  1. On your hosting provider (e.g. Railway → Settings → Custom domain), add ai-chat.appifire.com (this app’s subdomain).
  2. 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)
  3. Wait for SSL to provision (usually 1–5 minutes on Railway/Render).
  4. Verify: curl https://ai-chat.appifire.com/api/chat should 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.

  1. Go to railway.app and sign in.
  2. Click New ProjectDeploy from GitHub repo.
  3. Select the appifire-ai-chat repo (or the monorepo root — set the Root Directory to appifire-ai-chat/).

In Railway → your service → Variables, add:

VariableValue
SHOPIFY_API_KEYFrom Partner Dashboard → App → API credentials
SHOPIFY_API_SECRETFrom Partner Dashboard → App → API credentials
SHOPIFY_APP_URLhttps://ai-chat.appifire.com
SCOPESwrite_metaobject_definitions,write_metaobjects,write_products,read_products,read_inventory,read_content,read_themes
DATABASE_URLNeon pooled connection string (from Neon dashboard → Connection → Pooled)
DIRECT_URLNeon direct connection string (from Neon dashboard → Connection → Direct)
OPENROUTER_API_KEYFrom openrouter.ai → Keys
NODE_ENVproduction

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.

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.

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)”
  1. render.comNew Web Service → connect GitHub repo.
  2. Root Directory: appifire-ai-chat.
  3. Build command: npm install && npm run build.
  4. Start command: npm run setup && npm start.
  5. Add all environment variables (same as Railway table above).
  6. Add Custom domain: ai-chat.appifire.com in 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”.

  • 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 deploy succeeded on production DB (check Neon → Tables)
  • shopify app deploy run — extension and toml pushed to Shopify
  • App version in dev.shopify.com created with production URLs and set as active

Install the app fresh on a dev store and test every step:

  • OAuth install completes; shops row created in DB
  • Product sync triggers after install; products visible in knowledge_chunks and embeddings
  • 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 uninstalled in DB; sessions deleted
  • Webhooks delivered: check Partner Dashboard → Apps → your app → Webhooks for delivery logs
  • 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.com or https://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
  • Scopes in shopify.app.toml match 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”
  1. Open Partner DashboardAppsAppiFire AI Chat.
  2. In the left sidebar, click Distribution.
  3. Click Shopify App Store.
  4. Fill in the App listing form (name, description, screenshots, pricing, support info).
  5. Click Submit app.
  • 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).

They will install your app on a test store and verify:

  1. App installs without errors (OAuth completes, no 500 errors).
  2. The embedded admin UI loads inside Shopify Admin (no white screen, no auth loop).
  3. The app does what the listing says (chat widget appears, responds to questions).
  4. All stated scopes are actually used.
  5. Billing works (subscription flow doesn’t crash; test mode accepted during review).
  6. Uninstall works cleanly (no orphaned data issues, redirect errors).
  7. Privacy policy URL is live and accessible.
  8. GDPR webhooks are registered.

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]
Rejection reasonFix
”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

  • Webhook failures: Partner Dashboard → Apps → Webhooks → check for failed deliveries.
  • Error logging: add Sentry (npm install @sentry/node) and initialise in entry.server.jsx. Catches unhandled errors in production.
  • Neon DB: monitor connection count and query latency in Neon dashboard. Upgrade from free tier when needed.
  • 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.
  • Use the openrouter_calls and chat_messages tables to see what customers are asking. Improve your chunking and prompts based on real questions.
  • Add FAQ/policy documents as knowledge sources (extend knowledge_sources ingestion).
  • Consider adding email notifications (e.g. daily summary of replies used) to keep merchants engaged.

  • Backend deployed to Railway/Render at https://ai-chat.appifire.com
  • Custom domain SSL active; curl https://ai-chat.appifire.com/api/chat returns 200
  • All env vars set on host
  • Production DB migrations applied
  • shopify app deploy run; extension and config live in Shopify
  • Fresh install on dev store works end-to-end
  • Product sync, settings, widget, chat, billing all tested
  • Uninstall tested
  • 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
  • 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
  • Sentry (or equivalent) error tracking configured
  • Webhook delivery monitored
  • Review response process in place