Skip to main content
Met een aangepaste template kun je overschrijven hoe een individueel blok rendert. In plaats van de ingebouwde UI van het blok rendert de cart jouw eigen JSX, met dezelfde gegevens die het blok normaal zou gebruiken. Het is een overkoepelende mogelijkheid in plaats van een eigen blok: de meeste blokken bieden het aan via hun tabblad Code. Deze pagina behandelt wat voor elk blok geldt. Voor de props die een specifiek blok je geeft, ga je naar de eigen referentie van het blok.

Aangepaste template versus Custom code-blok

Deze klinken vergelijkbaar maar doen verschillende dingen:
  • Een aangepaste template vervangt de rendering van een bestaand blok door je eigen markup, en geeft je de eigen gegevens van dat blok (de titel en het aantal items van de Header, de totalen van de Summary, enzovoort). Het voegt niets nieuws toe; het herstylet één blok.
  • Het Custom code-blok voegt een nieuw blok toe met willekeurige HTML of React, overal in de cart.
Grijp naar een aangepaste template wanneer het ingebouwde blok bijna goed is maar je een andere lay-out of markup nodig hebt. Grijp naar een Custom code-blok wanneer je iets wilt toevoegen dat de ingebouwde blokken niet dekken.

Een aangepaste template gebruiken

  1. Selecteer een blok in de editor en open het tabblad Code.
  2. Bewerk de standaardtemplate. Aangepaste templates zijn alleen JSX (de keuze tussen HTML en JSX is exclusief voor het Custom code-blok).
  3. Klik op Compile. Compileren verwijdert de types en transpileert de JSX, dus het vangt syntaxfouten af. Typefouten stoppen een compile niet — de editor markeert die inline terwijl je typt, met dezelfde IntelliSense die de props van het blok automatisch aanvult.
  4. Zet de template aan zodat de cart deze gebruikt in plaats van de ingebouwde rendering.
  5. Reset to default herstelt op elk moment de oorspronkelijke template van het blok.

Een template schrijven met AI

Het Code-tabblad bevat een knop Copy AI prompt (✦ toverstaf-icoon). Erop klikken kopieert een op zichzelf staande briefing naar je klembord die je direct in een AI-chatsessie kunt plakken (Claude, ChatGPT of vergelijkbaar). De prompt bevat alles wat de AI nodig heeft om een geldige template voor dat specifieke blok te schrijven:
  • De compileregels (één expressie, geen export default, geen imports)
  • De exacte props die het blok ontvangt, overeenkomend met wat de IntelliSense van de editor toont
  • De vergrendelde functiesignatuur die de editor afdwingt
  • Blokspecifieke regels (geldformaten, welke handlers je moet koppelen, toegankelijkheidsvereisten)
  • Een invulsectie waar je je huidige template plakt en de gewenste wijziging beschrijft
Na het kopiëren open je een AI-sessie, plak je de prompt, vul je de twee lege velden onderaan in (je huidige template en de gewenste wijziging) en verstuur je hem. De AI geeft een complete template terug die je terug in de editor kunt plakken en compileren.
Plak je bestaande template in de invulsectie in plaats van deze leeg te laten. De AI gebruikt hem als startpunt, zodat elke aanpassing die je al hebt gedaan wordt meegenomen in plaats van vervangen door de standaard.
De prompt is specifiek per blok. De knop Copy AI prompt verschijnt alleen op blokken die aangepaste templates ondersteunen.
De standaardtemplate waarmee je begint is een werkende kopie van de ingebouwde markup van het blok, dus je hebt altijd een correcte, renderende referentie om aan te passen in plaats van een lege pagina. Grijp naar Reset to default wanneer je die referentie terug wilt.Het is niet altijd een byte-voor-byte-match. De standaardtemplate van de Header rendert ook logoUrl, waarvoor de ingebouwde markup geen plek heeft, dus het inschakelen van die template is hoe een geüploade headerafbeelding voor het eerst verschijnt.

Wat je template vervangt

Een template vervangt de rendering van het blok volledig. Er blijft geen wrapper rond je JSX over, wat gevolgen heeft die je moet kennen voordat je dingen gaat verwijderen:
Het Design-tabblad is degene waar mensen door worden verrast. Terwijl een aangepaste template actief is, zijn de velden van het Design-tabblad uitgeschakeld en verschijnt er een waarschuwingsicoon naast de kop “Design”. Beweeg over het icoon om te zien waarom. Style het blok in plaats daarvan vanuit je template, inline of met je eigen CSS. De velden worden weer ingeschakeld zodra je de aangepaste template uitzet.
Wat je behoudt: de positie van het blok in de cart, de zichtbaarheidsschakelaar, de instellingen (die nog steeds de props voeden die je ontvangt), het Custom CSS-paneel van de cart, en de ingebouwde laad-skeleton. Dat laatste verrast mensen. Het blok controleert of de cart nog aan het laden is voordat het je template bereikt, dus de ingebouwde skeleton rendert tijdens het laden en je template draait pas zodra de cart klaar is. Je hoeft geen laadstatus te bouwen.

Wat er beschikbaar is binnen een template

Je template is één functiecomponent. Deze compileert vanuit TSX, dus typeannotaties zijn toegestaan en worden bij het compileren verwijderd. Daarom zijn de standaardtemplates ermee geschreven:
De signatuurregel en de sluitende accolade zijn vergrendeld — de editor laat je geen van beide bewerken, en eroverheen bewegen toont “Locked — this line can’t be edited.” Je schrijft de body ertussen. Reset to default is het enige dat ze kan vervangen. Wat verder van belang is:
  • Je krijgt vijf hooks: useState, useEffect, useMemo, useRef en useCallback. Plus Fragment, voor <>…</>.
  • Er zijn geen imports. Je kunt niets importen, en er is geen React-object beschikbaar, dus geen React.useReducer, geen React.Children. Als een hook niet in de bovenstaande lijst staat, is hij niet beschikbaar.
  • Props zijn alleen-lezen. Een prop muteren doet niets nuttigs. Om de cart te wijzigen, gebruik je de handler-props die het blok je geeft (onClose, increment, selectPlan, enzovoort) in plaats van direct naar props te schrijven.
  • window is bereikbaar, dus een template kan de Cart SDK aanroepen via window.aftersell.cart wanneer het iets nodig heeft dat de props van het blok niet dekken.

Conventies voor elk blok

Drie regels gelden overal, en ze kennen neemt het meeste giswerk weg:
  • *Html-props zijn vooraf gesaneerde rich text. Render ze met dangerouslySetInnerHTML. Ze zijn al door de sanitizer van de cart gegaan, en merchant-tokens zoals {{total_price}} zijn al ingevuld.
  • Prijzen die als string binnenkomen, zijn al geformatteerd in het geldformaat van de winkel. Prijzen als number zijn in centen. Een blok geeft je het een of het ander, en de tabel van elk blok vermeldt welke.
  • isLoading is altijd false binnen een template. Het blok rendert zijn ingebouwde skeleton en roept je template pas aan zodra de cart is geladen, dus de prop wordt voor de volledigheid meegegeven en niet om op te vertakken.
Een paar blokken renderen in bepaalde statussen helemaal niets, zodat je template nooit met lege data wordt aangeroepen. De Rewards-template ziet nooit een lege milestones, en de Subscription upgrade-template ziet nooit een null view. De referentie van elk blok vermeldt waar dit van toepassing is, zodat je de lege-status-vertakking kunt overslaan.

Een aangepaste template stylen

De standaardtemplate waarmee je begint, draagt de classnames van het blok. Hoe je je bewerkingen stylet, hangt af van hoe ver je van dat startpunt afwijkt.

De twee class-families

Elk element in een standaardtemplate draagt een gepaarde classname, en ze doen heel verschillende dingen: Dus cart-internal-header__title is wat de titel eruit laat zien als de ingebouwde titel, en cart-external-header__title is het handvat dat je moet vastpakken wanneer je het uiterlijk wilt veranderen.

Kleine wijzigingen: behoud beide classnames

Als je elementen herschikt, herlabelt of iets toevoegt binnen de bestaande structuur, laat de classnames dan met rust. Je behoudt de ingebouwde look gratis, en je herstylet via Custom CSS gericht op de cart-external-*-haakjes.

Herstructureren: laat beide classnames vallen

Zodra je de DOM-structuur verandert in plaats van bijstelt, haal je beide families van je markup en gebruik je in plaats daarvan je eigen classnames. Voor elk is er een aparte reden. Laat cart-internal-* vallen omdat de ingebouwde CSS voor de ingebouwde DOM is geschreven. Houd die classes op geherstructureerde markup en je erft lay-outregels die uitgaan van elementen die je niet meer hebt: flex-containers die andere kinderen verwachten, spacing tussen verplaatste elementen, positionering ten opzichte van iets dat je hebt verwijderd. Dit uit zich meestal als je eigen CSS die “niet werkt” terwijl de ingebouwde regels winnen.
Laat cart-external-* vallen omdat het een gedeelde naam is, niet die van jou. Die classnames betekenen iets specifieks op de ingebouwde markup, en je Custom CSS wordt één keer geschreven voor de hele cart. Als een geherstructureerde template ze hergebruikt, target elke regel die je schrijft zowel jouw structuur als de ingebouwde.Dat gaat mis zodra je de aangepaste template uitzet: het blok valt terug op zijn ingebouwde markup, en je CSS wijst er nog steeds naar en stylet nu een DOM waarvoor hij nooit is geschreven. Je eigen prefix houdt de twee netjes gescheiden, zodat een template uitzetten een schone terugkeer is.
Twee manieren om te stylen wat je hebt gebouwd:

Optie 1: je eigen classnames plus Custom CSS

Het beste voor alles wat je gaat onderhouden of hergebruiken. Geef je classes een prefix waar niemand anders mee botst, meestal je winkel- of merknaam:
Selecteer vervolgens in de cart-editor Cart settings in het linkerpaneel en open het tabblad Custom CSS rechts:
Een prefix is belangrijker dan hij lijkt. Zonder prefix riskeert een class als .header of .title een botsing met de eigen classes van de cart, de template van een andere app of een toekomstig blok.

Optie 2: inline styles

Geen heen-en-weer naar het CSS-paneel, en alles staat op één plek:
Goed voor lay-outopbouw en eenmalige gevallen. De beperkingen zijn de gebruikelijke: geen :hover of andere pseudo-classes, geen media queries, en geen hergebruik over blokken heen. Grijp naar Optie 1 zodra je een van die dingen wilt.

Een aanpak kiezen

De cart rendert in een shadow root, dus de stylesheet van je thema kan er niet in reiken. Styles voor een aangepaste template moeten komen van het eigen Custom CSS-paneel van de cart of van inline styles, niet van je thema. Zie Aangepaste CSS.

Wanneer een template faalt

Een kapotte template breekt nooit de cart. Het blok rendert niets en alles eromheen blijft werken, wat veilig is maar makkelijk te missen: een lege plek waar je blok zou moeten staan, is het symptoom. Omdat het blok stilletjes verdwijnt in plaats van zichtbaar een fout te geven, controleer je een template altijd in de voorvertoning voordat je publiceert. Als een blok is verdwenen, open dan eerst de browserconsole. Twee dingen om op te letten, omdat beide een template laten crashen die anders veronderstelt:
  • Nullable props. Veel props zijn null onder normale omstandigheden (logoUrl zonder logo, imageUrl zonder afbeelding, variantTitle bij een product met één variant). Controleer voordat je ze gebruikt.
  • Arrays die leeg kunnen zijn. discountTags en discountCodes zijn vaker wel dan niet [].

Beperkingen

  • Aangepaste templates zijn weergave-overrides. Om logica op de cart uit te voeren (abonneren op events, items toevoegen, reageren op wijzigingen), gebruik je Aangepaste scripts en de Cart SDK.
  • Bijna elk blok ondersteunt er een. De uitzonderingen zijn het Express payments-blok, dat Shopify’s eigen betaalknoppen host, en de Cart items-container zelf, hoewel de Product-rij erbinnen wél een aangepaste template ondersteunt.
  • Een template kan niet veranderen wat een blok fundamenteel doet. Het verandert hoe de gegevens van het blok worden gepresenteerd, niet de gegevens of het gedrag erachter.

Props per blok

Elk blok geeft zijn eigen gegevens door. De volledige prop-tabel, met types en een uitgewerkt voorbeeld, staat op de pagina van dat blok: Het Custom code-blok is het enige vlak dat markup toevoegt in plaats van de rendering van een blok te vervangen, dus zijn props zijn anders: de hele cart, plus een add-to-cart-actie. Zie Custom code-blokken → Props.