> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aftersell.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Template personalizzati

> Sostituisci il rendering di qualsiasi blocco di Aftersell Cart con il tuo JSX: cosa sostituisce un template, cosa è disponibile, come stilizzarlo e dove trovare le prop di ogni blocco.

Un **template personalizzato** ti permette di sostituire il rendering di un singolo blocco. Al posto dell'interfaccia integrata del blocco, il carrello renderizza il tuo JSX, usando gli stessi dati che il blocco userebbe normalmente. È una capacità trasversale piuttosto che un blocco a sé: la maggior parte dei blocchi la espone dalla propria scheda **Code**.

Questa pagina copre ciò che si applica a **ogni** blocco. Per le prop che uno specifico blocco ti passa, vai al [riferimento del blocco stesso](#props-for-each-block).

<div id="custom-template-vs-custom-code-block">
  ## Template personalizzato vs. blocco Custom code
</div>

Sembrano simili ma fanno cose diverse:

* Un **template personalizzato** *sostituisce il rendering di un blocco esistente* con il tuo markup, e ti passa i dati di quel blocco (il titolo e il conteggio articoli dell'Header, i totali del Summary e così via). Non aggiunge nulla di nuovo; ristilizza un blocco.
* Il blocco **[Custom code](/it/aftersell/cart/custom-code-blocks)** *aggiunge un nuovo blocco* di HTML o React arbitrario ovunque nel carrello.

Ricorri a un template personalizzato quando il blocco integrato è quasi giusto ma ti serve un layout o un markup diverso. Ricorri a un blocco Custom code quando vuoi aggiungere qualcosa che i blocchi integrati non coprono.

<div id="using-a-custom-template">
  ## Usare un template personalizzato
</div>

1. Seleziona un blocco nell'editor e apri la sua scheda **Code**.
2. Modifica il template predefinito. I template personalizzati sono **solo JSX** (la scelta tra HTML e JSX è esclusiva del blocco Custom code).
3. Fai clic su **Compile**. La compilazione rimuove i tipi e transpila il JSX, quindi cattura gli errori di **sintassi**. Gli errori di tipo non bloccano una compilazione — l'editor li segnala inline mentre digiti, con lo stesso IntelliSense che completa automaticamente le prop del blocco.
4. Attiva il template per far sì che il carrello lo usi al posto del rendering integrato.
5. **Reset to default** ripristina il template originale del blocco in qualsiasi momento.

<div id="writing-a-template-with-ai">
  ## Scrivere un template con l'AI
</div>

La scheda Code include un pulsante **Copy AI prompt** (icona a bacchetta ✦). Facendovi clic copi negli appunti un brief autonomo che puoi incollare direttamente in una sessione di chat AI (Claude, ChatGPT o simili).

Il prompt include tutto ciò che serve all'AI per scrivere un template valido per quello specifico blocco:

* Le regole di compilazione (singola espressione, niente `export default`, niente import)
* Le prop esatte che il blocco riceve, corrispondenti a ciò che mostra l'IntelliSense dell'editor
* La firma di funzione bloccata che l'editor impone
* Regole specifiche del blocco (formati di denaro, quali handler collegare, requisiti di accessibilità)
* Una sezione da compilare dove incolli il tuo template attuale e descrivi la modifica che vuoi

Dopo aver copiato, apri una sessione AI, incolla il prompt, compila i due spazi in fondo (il tuo template attuale e la modifica che vuoi) e invia. L'AI restituisce un template completo che puoi incollare di nuovo nell'editor e compilare.

<Tip>
  Incolla il tuo template esistente nella sezione da compilare invece di lasciarla vuota. L'AI lo usa come punto di partenza, così qualsiasi personalizzazione che hai già fatto viene portata avanti invece di essere sostituita dal predefinito.
</Tip>

<Note>
  Il prompt è specifico per ogni blocco. Il pulsante **Copy AI prompt** appare solo sui blocchi che supportano i template personalizzati.
</Note>

<Tip>
  Il template predefinito da cui parti è una **copia funzionante del markup integrato del blocco**, così hai sempre un riferimento corretto e renderizzante da modificare anziché una pagina bianca. Usa **Reset to default** ogni volta che vuoi riavere quel riferimento.

  Non è sempre una corrispondenza byte per byte. Il template predefinito dell'Header renderizza anche `logoUrl`, per cui il markup integrato non ha un posizionamento, quindi attivare quel template è il modo in cui un'immagine dell'header caricata appare per la prima volta.
</Tip>

<div id="what-your-template-replaces">
  ## Cosa sostituisce il tuo template
</div>

Un template sostituisce il rendering del blocco **interamente**. Non resta alcun wrapper attorno al tuo JSX, il che ha conseguenze che vale la pena conoscere prima di iniziare a eliminare cose:

| Cosa perdi                                         | Cosa significa                                                                                                                                                                                                        |
| -------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| L'elemento wrapper del blocco                      | Nulla avvolge il tuo markup. Qualsiasi padding, allineamento o layout fornito dal blocco ora spetta a te.                                                                                                             |
| **Le impostazioni della scheda Design del blocco** | Le impostazioni di design vengono applicate come stili inline sul wrapper integrato, e quel wrapper non c'è più. Colori, spaziature e raggi impostati nella scheda Design **smettono di applicarsi** a questo blocco. |
| Le funzionalità di accessibilità integrate         | Gli `aria-label`, la gestione del focus e gli elementi semantici esistono solo se il tuo JSX li include.                                                                                                              |

<Warning>
  **La scheda Design è quella che sorprende le persone.** Mentre un template personalizzato è attivo, i campi della scheda Design sono disabilitati e un'icona di avviso appare accanto all'intestazione "Design". Passa il mouse sull'icona per vedere il perché. Stilizza invece il blocco dal tuo template, [inline o con il tuo CSS](#styling-a-custom-template). I campi si riabilitano non appena disattivi il template personalizzato.
</Warning>

Cosa mantieni: la posizione del blocco nel carrello, il suo interruttore di visibilità, le sue impostazioni (che continuano ad alimentare le prop che ricevi), il pannello [Custom CSS](/it/aftersell/cart/custom-css) del carrello e **lo skeleton di caricamento integrato**.

Quest'ultimo sorprende molti. Il blocco verifica se il carrello sta ancora caricando *prima* di raggiungere il tuo template, quindi lo skeleton integrato viene renderizzato durante il caricamento e il tuo template viene eseguito solo quando il carrello è pronto. Non devi costruire uno stato di caricamento.

<div id="whats-available-inside-a-template">
  ## Cosa è disponibile dentro un template
</div>

Il tuo template è un singolo componente funzione. Viene compilato da **TSX**, quindi le annotazioni di tipo sono consentite e rimosse in fase di compilazione. Ecco perché i template predefiniti sono scritti con esse:

```jsx theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
function Header(props: HeaderProps) {
  return <div>{/* … */}</div>;
}
```

**La riga della firma e la parentesi graffa di chiusura sono bloccate** — l'editor non ti lascia modificare nessuna delle due, e passandoci sopra il mouse appare "Locked — this line can't be edited." Scrivi il corpo tra di esse. **Reset to default** è l'unica cosa che può sostituirle.

Cos'altro conta:

* **Hai cinque hook:** `useState`, `useEffect`, `useMemo`, `useRef` e `useCallback`. Più `Fragment`, per `<>…</>`.
* **Non ci sono import.** Non puoi fare `import` di nulla, e non c'è un oggetto `React` disponibile, quindi niente `React.useReducer`, niente `React.Children`. Se un hook non è nell'elenco qui sopra, non è disponibile.
* **Le prop sono in sola lettura.** Mutare una prop non farà nulla di utile. Per modificare il carrello, usa le prop handler che il blocco ti dà (`onClose`, `increment`, `selectPlan` e così via) invece di scrivere direttamente sulle prop.
* **`window` è raggiungibile**, quindi un template può chiamare il [Cart SDK](/it/aftersell/cart/sdk-overview) tramite `window.aftersell.cart` quando gli serve qualcosa che le prop del blocco non coprono.

<div id="conventions-across-every-block">
  ## Convenzioni comuni a tutti i blocchi
</div>

Tre regole valgono ovunque, e conoscerle elimina la maggior parte dei dubbi:

* **Le prop `*Html` sono rich text pre-sanificato.** Renderizzale con `dangerouslySetInnerHTML`. Sono già passate attraverso il sanificatore del carrello, e i token del merchant come `{{total_price}}` sono già risolti.
* **I prezzi che arrivano come `string` sono già formattati** nel formato di denaro del negozio. I prezzi come `number` sono in centesimi. Un blocco ti dà l'uno o l'altro, e la tabella di ogni blocco indica quale.
* **`isLoading` è sempre `false` dentro un template.** Il blocco renderizza il suo skeleton integrato e chiama il tuo template solo quando il carrello è stato caricato, quindi la prop viene passata per completezza, non perché tu debba ramificare su di essa.

<Note>
  Alcuni blocchi non restituiscono nulla in certi stati, quindi il tuo template non viene mai chiamato con dati vuoti. Il template di Rewards non vede mai `milestones` vuoto, e il template di Subscription upgrade non vede mai una `view` null. Il riferimento di ogni blocco indica dove questo si applica, così puoi saltare il ramo dello stato vuoto.
</Note>

<div id="styling-a-custom-template">
  ## Stilizzare un template personalizzato
</div>

Il template predefinito da cui parti contiene i nomi di classe del blocco. Come stilizzi le tue modifiche dipende da quanto ti allontani da quel punto di partenza.

<div id="the-two-class-families">
  ### Le due famiglie di classi
</div>

Ogni elemento in un template predefinito porta un nome di classe accoppiato, e le due famiglie fanno lavori molto diversi:

| Famiglia          | Cosa fa                                                                                                                      | Scriverci CSS contro?                                                                            |
| ----------------- | ---------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| `cart-internal-*` | **Porta lo stile integrato del blocco.** Ogni regola nel foglio di stile del carrello punta a questa famiglia.               | No. È la struttura interna del carrello, e l'editor Custom CSS segnala i selettori che la usano. |
| `cart-external-*` | **Un gancio senza stile proprio.** Nulla nel foglio di stile del carrello la usa; esiste perché il tuo CSS possa afferrarla. | Sì. È il modo supportato per ristilizzare un blocco.                                             |

Quindi `cart-internal-header__title` è ciò che fa *sembrare* il titolo come il titolo integrato, e `cart-external-header__title` è la maniglia che dovresti afferrare quando vuoi cambiarne l'aspetto.

<div id="small-changes-keep-both-classnames">
  ### Piccole modifiche: mantieni entrambi i nomi di classe
</div>

Se stai riordinando elementi, rietichettando o aggiungendo qualcosa dentro la struttura esistente, lascia stare i nomi di classe. Mantieni gratis l'aspetto integrato, e ristilizzi tramite il [Custom CSS](/it/aftersell/cart/custom-css) puntando ai ganci `cart-external-*`.

<div id="restructuring-drop-both-classnames">
  ### Ristrutturazione: elimina entrambi i nomi di classe
</div>

Quando cambi la struttura del DOM invece di ritoccarla, togli **entrambe** le famiglie dal tuo markup e usa [i tuoi nomi di classe](#option-1-your-own-classnames-plus-custom-css). C'è un motivo distinto per ciascuna.

**Elimina `cart-internal-*` perché il CSS integrato è stato scritto per il DOM integrato.** Mantieni quelle classi su markup ristrutturato ed erediti regole di layout che presuppongono elementi che non hai più: contenitori flex che si aspettano figli diversi, spaziature tra elementi spostati, posizionamento relativo a qualcosa che hai rimosso. Questo di solito si manifesta come il tuo CSS che "non funziona" quando in realtà sono le regole integrate a vincere.

<Warning>
  **Elimina `cart-external-*` perché è un nome condiviso, non tuo.** Quei nomi di classe hanno un significato specifico sul markup integrato, e il tuo Custom CSS viene scritto una sola volta per l'intero carrello. Se un template ristrutturato li riusa, ogni regola che scrivi colpisce sia la tua struttura sia quella integrata.

  Le cose vanno male nel momento in cui disattivi il template personalizzato: il blocco torna al suo markup integrato, e il tuo CSS continua a puntarci, stilizzando ora un DOM per cui non è mai stato scritto. Un tuo prefisso mantiene i due nettamente separati, così disattivare un template è un ripristino pulito.
</Warning>

Due modi per stilizzare ciò che hai costruito:

<div id="option-1-your-own-classnames-plus-custom-css">
  #### Opzione 1: i tuoi nomi di classe più Custom CSS
</div>

La scelta migliore per qualsiasi cosa che manterrai o riuserai. Dai alle tue classi un prefisso con cui nessun altro entrerà in conflitto, di solito il nome del tuo negozio o brand:

```jsx theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
function Header(props) {
  return (
    <div className="northwind-custom-header">
      <div className="northwind-custom-header__title" dangerouslySetInnerHTML={{ __html: props.title }} />
      <button type="button" className="northwind-custom-header__close" onClick={props.onClose}>
        &times;
      </button>
    </div>
  );
}
```

Poi nel cart editor, seleziona **Cart settings** nel pannello sinistro e apri la scheda **Custom CSS** a destra:

```css theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
.northwind-custom-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px;
}

.northwind-custom-header__title {
  font-size: 18px;
  font-weight: 600;
}

.northwind-custom-header__close:hover {
  opacity: 0.6;
}
```

Un prefisso conta più di quanto sembri. Senza, una classe come `.header` o `.title` rischia di entrare in conflitto con le classi del carrello, con il template di un'altra app o con un blocco futuro.

<div id="option-2-inline-styles">
  #### Opzione 2: stili inline
</div>

Nessun andirivieni con il pannello CSS, e tutto vive in un unico posto:

```jsx theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
<div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
```

Ottimo per l'impalcatura del layout e per soluzioni una tantum. I suoi limiti sono quelli soliti: niente `:hover` o altre pseudo-classi, niente media query e nessun riuso tra blocchi. Passa all'Opzione 1 quando ti serve una di queste cose.

<div id="picking-an-approach">
  ### Scegliere un approccio
</div>

| Situazione                                     | Fai così                                                                                          |
| ---------------------------------------------- | ------------------------------------------------------------------------------------------------- |
| Stessa struttura, testo o ordine diverso       | Mantieni entrambi i nomi di classe, ristilizza via Custom CSS su `cart-external-*`                |
| Nuova struttura, stile che manterrai           | Le tue classi con prefisso, entrambe le famiglie del carrello eliminate                           |
| Nuova struttura, poche regole di layout rapide | Stili inline, entrambe le famiglie del carrello eliminate                                         |
| Tanto codice personalizzato su più blocchi     | Le tue classi con prefisso ovunque, così qualsiasi template può essere disattivato senza problemi |

<Note>
  Il carrello viene renderizzato in uno shadow root, quindi il foglio di stile del tuo tema non può raggiungerne l'interno. Gli stili per un template personalizzato devono arrivare dal pannello **Custom CSS** del carrello o da stili inline, non dal tuo tema. Consulta [CSS personalizzato](/it/aftersell/cart/custom-css).
</Note>

<div id="when-a-template-fails">
  ## Quando un template fallisce
</div>

Un template rotto non rompe mai il carrello. Il blocco non renderizza **nulla** e tutto ciò che lo circonda continua a funzionare, il che è sicuro ma facile da non notare: uno spazio vuoto dove dovrebbe esserci il tuo blocco è il sintomo.

| Errore                        | Quando lo vedrai               | Dove viene segnalato                                                                                                                  |
| ----------------------------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- |
| Errore di tipo                | Mentre digiti                  | Una sottolineatura ondulata inline nell'editor. **Non** blocca la compilazione — il compilatore rimuove i tipi invece di controllarli |
| Errore di sintassi            | Quando fai clic su **Compile** | Nell'editor, prima che possa raggiungere il tuo negozio                                                                               |
| Un crash durante il rendering | Sul negozio, una volta attivo  | `console.error('[aftersell-cart] module crashed: …')`                                                                                 |

Poiché il blocco scompare silenziosamente invece di mostrare un errore visibile, controlla sempre un template in [anteprima](/it/aftersell/cart/previewing-carts) prima di pubblicare. Se un blocco è sparito, apri prima la console del browser.

Due cose da cui proteggersi, dato che entrambe fanno crashare un template che presume il contrario:

* **Prop nullable.** Molte prop sono `null` in condizioni normali (`logoUrl` senza logo, `imageUrl` senza immagine, `variantTitle` su un prodotto a variante singola). Verificale prima di usarle.
* **Array che possono essere vuoti.** `discountTags` e `discountCodes` sono `[]` molto più spesso di quanto pensi.

<div id="limitations">
  ## Limitazioni
</div>

* **I template personalizzati sono override di visualizzazione.** Per eseguire logica sul carrello (iscriverti agli eventi, aggiungere articoli, reagire alle modifiche), usa gli [script personalizzati](/it/aftersell/cart/custom-scripts) e il [Cart SDK](/it/aftersell/cart/sdk-overview).
* **Quasi tutti i blocchi ne supportano uno.** Le eccezioni sono il blocco **[Express payments](/it/aftersell/cart/express-payments-block)**, che ospita i pulsanti di pagamento di Shopify, e il contenitore **[Cart items](/it/aftersell/cart/cart-items-block)** stesso, anche se la riga **Product** al suo interno supporta un template personalizzato.
* **Un template non può cambiare ciò che un blocco fa fondamentalmente.** Cambia come i dati del blocco vengono presentati, non i dati o il comportamento sottostante.

<div id="props-for-each-block">
  ## Prop per ogni blocco
</div>

Ogni blocco passa i propri dati. La tabella completa delle prop, con tipi e un esempio funzionante, si trova nella pagina di quel blocco:

| Blocco                                                                                | Prop che riceve                                                                                                                    |
| ------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| [Header](/it/aftersell/cart/header-block#custom-template)                             | `title`, `logoUrl`, `leftSection`, `rightSection`, `itemCount`, `onClose`, `isLoading`                                             |
| [Banner](/it/aftersell/cart/banner-block#custom-template)                             | `text`, `shouldUseTimer`, `isTimerExpiredAndShouldHide`, `isLoading`                                                               |
| [Rewards](/it/aftersell/cart/rewards-block#custom-template)                           | `milestones`, `rewardsMessageHtml`, `showIcons`, `isLoading`                                                                       |
| [Cart items · Product](/it/aftersell/cart/cart-items-block#custom-template)           | 25 prop: contenuto per riga, identificatori e controlli di quantità                                                                |
| [Subscription upgrade](/it/aftersell/cart/subscription-upgrade-block#custom-template) | `view`, `selectPlan`, `onChange`, `oneTimeValue` e altro                                                                           |
| [Summary](/it/aftersell/cart/summary-block#custom-template)                           | `leftHtml`, `rightHtml`, `discountCodes`, `totalPrice`, `savings` e altro                                                          |
| [Checkout button](/it/aftersell/cart/checkout-button-block#custom-template)           | `label`, `href`, `isLoading`                                                                                                       |
| [Discount code](/it/aftersell/cart/discount-code-block#custom-template)               | `discountCodeInput`, `placeholder`, `buttonText`, `isValidating`, `isInvalid`, `setDiscountCodeInput`, `handleSubmit`, `isLoading` |
| [Empty cart](/it/aftersell/cart/empty-cart-block#custom-template)                     | `text`, `cta`, `href`                                                                                                              |
| [Image](/it/aftersell/cart/image-block#custom-template)                               | `imageUrl`, `altText`, `maxHeight`, `fullWidth`                                                                                    |
| [Notes](/it/aftersell/cart/notes-block#custom-template)                               | `titleHtml`, `placeholder`, `noteInput`, `status`, `isExpanded`, `onNoteChange`, `onNoteBlur`, `onToggle` e altro                  |
| [Product add-on](/it/aftersell/cart/product-add-on-block#custom-template)             | `addonTitleHtml`, `descriptionHtml`, `priceHtml`, `imageUrl`, `format`, `isEnabled`, `handleAdd`, `handleToggle` e altro           |
| [Shipping protection](/it/aftersell/cart/shipping-protection-block#custom-template)   | `titleHtml`, `descriptionHtml`, `priceHtml`, `imageUrl`, `format`, `isEnabled`, `handleAdd`, `handleToggle` e altro                |
| [Upsells](/it/aftersell/cart/upsells-block#custom-template)                           | `title`, `addButtonText`, `layout`, `upsells`, `selectVariant`, `handleAdd` e i controlli del carosello                            |

Il blocco [Custom code](/it/aftersell/cart/custom-code-blocks) è l'unica superficie che **aggiunge** markup invece di sostituire il rendering di un blocco, quindi le sue prop sono diverse: l'intero carrello, più un'azione di aggiunta al carrello. Consulta [Blocchi Custom code → Prop](/it/aftersell/cart/custom-code-blocks#props).
