import { json, type LoaderFunctionArgs } from "@remix-run/node";
import { useLoaderData } from "@remix-run/react";
import { Page, Layout, Card, Text, BlockStack, SkeletonBodyText } from "@shopify/polaris";
import { authenticate } from "../shopify.server";
export const loader = async ({ request }: LoaderFunctionArgs) => {
const { admin, session } = await authenticate.admin(request);
const response = await admin.graphql(`
#graphql
query getShopInfo {
shop {
name
email
myshopifyDomain
}
}
`);
const { data } = await response.json();
return json({ shop: data.shop, shopDomain: session.shop });
};
export default function Index() {
const { shop } = useLoaderData<typeof loader>();
return (
<Page title="Setări Aplicație">
<Layout>
<Layout.Section>
<Card>
<BlockStack gap="300">
<Text as="h2" variant="headingMd">
Magazin conectat: {shop.name}
</Text>
<Text as="p" tone="subdued">
Domeniu admin: {shop.myshopifyDomain}
</Text>
</BlockStack>
</Card>
</Layout.Section>
</Layout>
</Page>
);
}Anul trecut am migrat un app legacy de Shopify de la Node+React clasic la stack-ul oficial bazat pe Remix și Polaris. Dacă vrei să trimiți o aplicație în App Store fără să-ți smulgi părul din cap, combinația asta e cam singura opțiune rațională astăzi. Totuși, procesul de review al celor de la Shopify a devenit mult mai strict decat era acum doi sau trei ani.
Setup-ul: De ce Remix și Polaris?
Dacă dai un npm create @shopify/app@latest, primești direct tot boilerplate-ul gata configurat: Remix, App Bridge și Polaris v12. Polaris e design system-ul lor nativ. Când un comerciant deschide aplicația ta în dashboard, nici nu-și dă seama că a ieșit din interfața nativă Shopify.
La un proiect recent pentru un client cu peste 12k comenzi lunare, am economisit în jur de 30% din timpul de frontend doar folosind componentele lor preconfigurate (Page, Layout, Card, ResourceList). Trade-off-ul? Polaris este extrem de rigid. Dacă vrei layout-uri exotice sau un branding complet customizat, te vei lupta cu framework-ul la fiecare pas. Sfatul meu e să nu încerci să reinventezi roata: fă UI-ul exact cum vrea Shopify, altfel review-ul va fi un coșmar.
Auth și Session Tokens fără dureri de cap
Trece vremea când gestionai manual cookiile de sesiune și OAuth-ul. Prin template-ul de Remix, totul se reduce la apelul authenticate.admin(request) în loader-e și action-uri. Remix se ocupă de token exchange în fundal prin App Bridge.
Partea proastă e că iframe-ul din Shopify Admin încă suferă pe Safari din cauza restricțiilor de third-party cookies. Dacă nu testezi aplicația specific pe Safari cu opțiunea de Iframe Protection activă, te trezești cu bucle infinite de redirect la autentificare în producție.
Ghid de supraviețuire pentru App Review
La ultimul submission am trecut prin 3 respingeri succesive până când echipa lor de QA a fost mulțumită. Oamenii de la Shopify testează manual aplicația pe magazine de dev și folosesc un bot automatizat care verifică scenarii de eroare.
Iată principalele motive pentru care îți vor respinge aplicația:
- Lipsa stărilor de loading (UI jank): Dacă dai click pe un buton și durează mai mult de 200-300ms fără un
Spinnersau componente de tipSkeleton, aplicația este respinsă direct. - Eroare necriptică pe GraphQL: Dacă cade un request către API-ul lor și aplicația afișează o pagină albă sau o eroare neformatată, primești flit. Trebuie să prinzi orice eroare și să o afișezi într-un component Polaris
Bannercu stare decritical. - Gestionarea webhook-urilor de dezinstalare: Când magazinul îți șterge app-ul, primești webhook-ul
APP_UNINSTALLED. Dacă botul lor reinstalează aplicația imediat și găsește date vechi orfane care blochează fluxul de on-boarding, ești picat.
Concluzie
Combinatia Remix + Polaris te scutește de luni de muncă de arhitectură, dar te obligă să joci 100% după regulile lor vizuale și de performanță. Dacă respecți ghidul lor de UX din prima zi, scapi de nervi la review.
Voi ce experiențe ați avut recent cu review-ul de la Shopify? Câte runde de feedback ați îndurat la ultimul app lansat?