import { json, LoaderFunctionArgs } from "@remix-run/node";
import { authenticate } from "../shopify.server";
export const loader = async ({ request }: LoaderFunctionArgs) => {
const { billing, session } = await authenticate.admin(request);
// Verificăm dacă magazinul are un abonament activ
const billingCheck = await billing.check({
plans: ["Plan Premium"],
isTest: process.env.NODE_ENV !== "production",
});
if (!billingCheck.hasActivePayment) {
// Redirecționăm către pagina de plată (cerință obligatorie la review-ul Shopify)
return billing.request({
plan: "Plan Premium",
isTest: process.env.NODE_ENV !== "production",
returnUrl: `https://${session.shop}/admin/apps/my-app/billing-success`,
});
}
return json({ shop: session.shop });
};Am pus recent în producție o aplicație Shopify publică folosind stack-ul lor oficial cu Remix și Polaris. După trei respingeri la review și câteva nopți pierdute cu sesiunile offline, am reușit s-o trecem de linia de sosire. Dacă vrei să intri pe App Store, scutisește-ți câteva zile de muncă citind ce am pățit noi.
Setup-ul cu Remix și de ce nu e totul roz
Shopify îți pune în mână un template gata configurat prin @shopify/shopify-app-remix. La prima vedere, e magie curată. Dai o comandă în terminal, ai CLI-ul pornit, baza de date SQLite configurată local și tunnel-ul Cloudflare activ în spate. În 10 minute ai o aplicație care rulează în iframe-ul din admin-ul unui magazin de test.
Dar magia se termină repede când trebuie să înțelegi cum circulă token-urile de sesiune. Remix folosește loaders și actions pentru a gestiona request-urile pe server. Când comerciantul intră în aplicație, Shopify trimite un session token în header. Dacă vrei să faci un simplu fetch din frontend către o rută proprie fără să treci prin utilitarele lor, te lovești de CORS și sesiuni invalide. Am pierdut vreo 6 ore doar ca să mă prind că trebuie să folosesc wrapper-ul lor de fetch peste tot în client, altfel middleware-ul de pe server respinge request-ul.
Trade-off-ul sincer: Polaris vs. Design Custom
Polaris este biblioteca lor de componente React, creată ca să ofere o experiență unitară în admin.
- Unde strălucește: Aplicația ta arată exact ca admin-ul nativ Shopify. Comercianții au încredere în ea instant pentru că nu simt că au părăsit platforma. În plus, accesibilitatea (A11y) este rezolvată din start.
- Unde e nasol: Personalizarea este un coșmar administrativ. Dacă clientul tău vrea un branding specific, culori custom sau elemente de UI non-standard, Polaris îți va pune bețe în roate la fiecare pas. E gândit să fie rigid tocmai ca să păstreze consistența. Pentru un MVP sau o aplicație pur utilitară, e perfect. Pentru un produs unde design-ul e diferențiatorul principal, mai bine folosești Tailwind și îți asumi că review-ul Shopify va fi mult mai atent la detalii.
Cum am rezolvat coșmarul de la review
Review-ul Shopify nu e o glumă automatizată. Un om real îți instalează aplicația pe un magazin de test și încearcă activ să o strice. Noi am avut aplicația testată pe un magazin cu peste 1.200 de produse fictive pentru a vedea cum se comportă paginarea și performanța.
Am fost respinși din două motive mari, pe care documentația le menționează doar în treacăt. În primul rând, fluxul de billing. Dacă magazinul de test este pe un plan de dezvoltare, aplicația ta trebuie să detecteze asta și să folosească modul de test pentru facturare, altfel testerul nu poate finaliza flow-ul de plată fictivă. În al doilea rând, reinstalarea rapidă: testerul a instalat aplicația, a șters-o și a reinstalat-o după 5 secunde. Baza noastră de date a păstrat sesiunea veche, iar aplicația a crăpat la re-autentificare. Am rezolvat asta curățând sesiunile vechi pe webhook-ul de APP_UNINSTALLED.
Voi ce stack folosiți pentru aplicațiile de Shopify? V-ați lovit și voi de rigiditatea Polaris sau ați mers pe Tailwind și design complet custom din prima zi?