eduardweb.
ShopifyIntermediar#typescript#fullstack#shopify#polaris#remix

Cum treci un app de Shopify prin App Store Review cu Remix și Polaris

De Bogdan Răducanu, 19 aug. 2026 · 13 vizualizări · 3 like-uri

Postat 19 aug. 2026
typescript
import type { ActionFunctionArgs } from "@remix-run/node";
import { authenticate } from "../shopify.server";
import { queueGdprJob } from "~/jobs/gdpr.server";

export const action = async ({ request }: ActionFunctionArgs) => {
  const { topic, shop, payload } = await authenticate.webhook(request);

  if (!shop) {
    return new Response("Missing shop", { status: 400 });
  }

  switch (topic) {
    case "CUSTOMERS_DATA_REQUEST":
    case "CUSTOMERS_REDACT":
    case "SHOP_REDACT":
      // Procesăm asincron în background, dăm 200 imediat
      await queueGdprJob({ topic, shop, payload });
      return new Response(null, { status: 200 });
    default:
      return new Response("Unhandled webhook topic", { status: 404 });
  }
};

Luna trecută am lansat o aplicație de sync pentru stocuri în Shopify App Store, după vreo trei săptămâni de lucru și exact trei respingeri la review. Dacă vrei să publici un app public, stack-ul oficial recomandat (Remix + Polaris via @shopify/shopify-app-remix) este cea mai rapidă cale, dar procesul de QA de la Shopify te lovește exact unde nu te aștepți.

Nu te baza pe ideea că dacă merge local în shopify app dev, ești gata de lansare. Uite câteva chestii concrete pe care le-am învățat pe propria piele.

De ce Polaris e sfânt (și unde devine frustrant)

Reviewerii de la Shopify au un checklist strict de UX. Dacă încerci să reinventezi roata cu Tailwind sau shadcn/ui în adminul magazinului, îți complici viața masiv. Dacă folosești componentele din @shopify/polaris, bifezi din start consistența vizuală, suportul pentru dark mode și accesibilitatea.

Trade-off-ul? Polaris e rigid. În momentul în care vrei un layout mai atipic sau o animație custom, te lupți cu design system-ul lor. La un tabel complex unde aveam nevoie de bulk actions combinate cu filtre custom, am pierdut 6 ore doar ca să aliniez comportamentul cu ce aștepta App Bridge-ul.

Regula de aur pentru review: fiecare pagină trebuie să aibă un Page wrapper cu title, iar dacă nu ai date, ești OBLIGAT să pui o componentă de EmptyState. Mi-au respins primul build fix pentru că pe ecranul de setări aveam un ecran gol până venea primul sync.

Cele 3 capcane din App Store Review

  1. GDPR Webhooks obligatorii: Shopify nu te lasă nici măcar să trimiți aplicația la review fără customers/data_request, customers/redact și shop/redact. Webhook-urile astea trebuie să răspundă cu 200 OK imediat (sub 3-4 secunde), altfel Shopify le reîncearcă și îți marchează endpoint-ul ca instabil. Nu procesa datele direct în request; aruncă payload-ul într-o coadă (eu folosesc BullMQ cu Redis) și dă return imediat.

  2. Session Storage și Safari ITP: În Remix, template-ul vine default cu Prisma session storage. Dacă rulezi pe un VPS mic sau pe serverless fără connection pooling (cum am pățit eu la un test pe Vercel), sesiunile se pierd când Safari blochează third-party cookies în iframe. Asigură-te că folosești token exchange-ul nou din App Bridge v4, unde autentificarea se face prin id token, nu prin cookies clasice.

  3. Billing API integrat corect: Dacă app-ul tău costă bani, nu accepta plăți prin Stripe extern sau link-uri custom. Trebuie să treci 100% prin Shopify Billing API. Reviewerul intră pe un store de test, încearcă să instaleze, declanșează plata de test și verifică dacă redirectionarea înapoi în app se face fără refresh complet de pagină.

Concluzie

Setup-ul Remix + Polaris îți ia cam 70% din durerea de cap pe partea de boilerplate și auth, dar celelalte 30% — adică compliance-ul Shopify — cer atenție la detalii. Dacă ai grijă la empty states, răspunzi instant la webhook-urile de GDPR și folosești App Bridge nativ, scapi de ping-pong-ul de 2 săptămâni cu echipa lor de QA.

Voi ce stack folosiți când faceți app-uri de Shopify? Ați rămas pe Node/Remix sau ați migrat spre extensii strict pe Storefront / Functions?

Răspunsuri 0

Se încarcă răspunsurile…

Loghează-te pentru a răspunde

Doar membrii comunității pot lăsa comentarii.