Szerveroldali renderelés: szabályok a témakódhoz
Mi változik a szerver rendererben futó témakódnál: megosztott module scope, időkezelés, szerveroldali fetch, SSR-assetek, árazási mód és bundle-korlátok.
Ezen az oldalon
A webáruház minden oldala a szerveren rendereli a theme code snippetjeit (header, lábléc, szekciók, blokkok, témaoldalak, pénztár- és fióksablonok), a böngésző pedig ezután hidratálja ugyanazt a jelölést. Ez minden boltra és minden témára érvényes.
A legtöbb témakódon nem kell módosítani. Az alábbi szabályok azt fedik le, ami eltérően működik egyetlen böngészőlaphoz képest.
A module scope minden vásárlónál közös
A moduljaid egyszer töltődnek be, majd a bolt összes vásárlójának egyszerre renderelnek oldalakat. Bármit, ami module scope-ban van (egy cache-ként használt Map, egy tömb, amibe elemeket fűzöl, egy let számláló), a következő vásárló renderelése is látja – akár a tiéd kellős közepén.
- A kérésenkénti állapotot tartsd a React state-ben, propokban vagy kontextusban.
- A modulszintű cache rendben van a boltszintű nyilvános adatokhoz (egy CMS-válasz, amit minden vásárló lát), de soha ne használd semmire, ami a vásárlóhoz kötődik: kosár, vásárló, nyelvi választás, keresés.
- A platform által átadott kontextusok (beállítások, üzenetek, a téma dokumentuma) zároltak (frozen); módosításuk hibát dob.
A témaellenőrző figyelmeztet (module-state), ha egy modulszintű tároló vagy let egy függvény belsejéből módosul. Ez figyelmeztetés, nem hiba: egy boltszintű cache legitim megoldás, és egyedül te tudod, milyet írtál.
Az időt a komponenseken belül kérd le
A module scope-ban lekért idő elavult: a Date.now(), a performance.now() és a new Date() ott egy olyan időpontot ad vissza, amely jóval az aktuális renderelés előtt volt. Egy modulszintű „új” jelvény, visszaszámláló vagy cache timestamp minden későbbi vásárlónál hibás lesz.
Az időt abban a komponensben vagy loaderben kérd le, amelyiknek szüksége van rá. A témaellenőrző figyelmeztet (module-state) a module scope-ban végzett időlekérésekre.
Események egy snippeten belül
Minden snippet saját React rootként hidratálódik. Egy snippeten belüli event handler, amely meghívja az e.stopPropagation() függvényt, a platform által a document-hez csatolt figyelők (analitika, a kosárfiókon kívüli kattintás, billentyűparancsok) elől is elrejti az eseményt. Csak akkor állítsd le a propagationt, ha az eseményt valóban el akarod rejteni az egész oldal elől.
A lassú fetch a fallback nézetét rendereli
A szerveroldali lekéréseknek gyorsnak kell lenniük. Ha valamelyik lassú, az oldal nem vár rá: a szerver minden még várakozó Suspense határt a fallback állapotában küld el, és a böngésző a hidratálás után rendereli le. A dizájnod így is megjelenik, és csak a várakozó rész késik.
- A szerveren lekért adatokat helyezd egy értelmes fallbackkel ellátott
Suspensehatár mögé. - A timeout miatt meghiúsuló fetch típusos hibát dob, amit a legközelebbi határ kap el.
- A folyamatosan hibát adó hosztot a rendszer egy ideig kihagyja, így a hozzá tartozó határok azonnal fallback állapotba lépnek.
Szerveroldali fetch
A szerveroldali renderelés alatti fetch() eléri a nyilvános internetet:
https:a 443-as porton éshttp:a 80-as porton, nyilvános hosztnevekre. Privát hálózatok, IP-címek és helyi nevek nem érhetők el.- A kérés a saját request headerjeidet is elküldi, beleértve a
cookie-t és azauthorization-t is, így meghívhatod a saját API-dat a kulcsoddal. - A status code és a response headerek eljutnak a kódodhoz. Egy szerveroldali válaszból semmi sem kerül át a vásárló headereibe vagy cookie-jaiba.
network.allow
Sorold fel a témád által meghívott hosztokat a theme.json fájlban, hogy csak ezekre korlátozd:
{
"network": { "allow": ["cms.example.com", "*.cdn.example.org"] }
}Az example.com csak saját magára illeszkedik. A *.example.com minden alatta lévő névre illeszkedik, de magára az example.com-ra nem. A network.allow nélkül a téma bármely nyilvános hosztot meghívhatja. Ha közzétételkor a téma olyan hosztot érne el, amelyet a közzétett verzió nem tudott (új hoszt, vagy a lista teljes elhagyása), a kereskedőnek meg kell erősítenie az új hosztokat a téma oldalán, mielőtt élesbe menne. Egy szűkebb lista vagy a legelső lista nem igényel megerősítést.
Bundle-fájlok olvasása SSR közben: assets.ssr
Az import data from './stores.json' működik: a build beágyazza (inline) a fájlt a kódodba.
Azokat a szövegfájlokat, amelyeket ehelyett a rendereléskor szeretnél beolvasni, sorold fel a theme.json fájlban:
{
"assets": { "ssr": ["src/data/stores.json", "src/content/faq.md"] }
}- Csak
.json,.txt,.md,.svgés.csvfájlok, egyenként legfeljebb 256 KiB méretben, a témán belüli elérési utakkal. - A szerveroldali renderelés során a
fetch('/theme-assets/assets/src/content/faq.md')a témából válaszol, és minden olyan fájlt elutasít, amely nem szerepel a listában. Ez az útvonal csak a szerveren ad választ. A böngészőben inkább importáld a fájlt.
Árazás: inline vagy islands
A theme.json beállíthatja a "pricing": "inline" (az alapértelmezett) vagy a "pricing": "islands" értéket.
Minden ár, amit egy téma megkap, egy PriceView a @poltura/theme-sdk/price csomagból: egy ref, amelybe a webáruház beilleszti az árat, valamint a resolved, a kiszámított összegek. Megjelenítheted a Price, PriceRange, CompareAtPrice, DiscountBadge vagy UnitPrice komponensekkel; az összegeket csak akkor olvasd ki a usePrice(price) hookkal, ha a kódnak számolnia kell velük.
inline: mindenPriceViewfeloldva érkezik.islands: a kezdőlapon, a kategóriaoldalakon, a/productsoldalon és a header kiemelt keresési termékeinél mindenPriceViewcsak arefmezőjét hordozza, ausePricenull értéket ad vissza, az árelemek pedig a webáruház által beillesztett élő árakat mutatják. A termékoldalon mindkét módban feloldva maradnak az árak. Csak akkor válaszd azislandsmódot, ha a komponenseid ezeken az oldalakon soha nem végeznek számításokat a feloldott összegekkel.
Az alapértelmezett téma islandeket renderel. Az a téma, amelynek kódja még megegyezik az alapértelmezett témáéval, deklaráció nélkül is islands módban épül fel; amint módosítod a kódját, inline módban épül, hacsak a theme.json másképp nem rendelkezik.
Bundle-korlátok
A buildelt téma szerveroldali részének meg kell felelnie ezeknek a korlátoknak, különben a build meghiúsul a THEME_GRAPH_LIMITS hibakóddal:
- legfeljebb 256 modul (a szerveroldali
.jsfájlok plusz azassets.ssrfájlok); - legfeljebb 1 MiB modulonként;
- legfeljebb 8 route segment és 200 karakter fájlelérési utanként, ahol minden szegmens betűvel vagy számjeggyel kezdődik.
Az érvénytelen assets.ssr, network.allow vagy pricing beállítás miatt a build meghiúsul a THEME_SETTINGS_INVALID hibakóddal, és a témaellenőrző ezt jelzi a theme.json fájlban.
Következő lépések
- Stabil chrome class-ok: szabd át a platform headerjét, kosarát és chatfelületeit CSS-ből.
- Téma-assetek és média: mellékelj képeket és betűtípusokat a témához.