Chi Siamo Area Clienti Promo del Mese Dicono di Noi Portfolio FAQ Blog
HTML

Il Tag Template in HTML: Creare Componenti Riutilizzabili

Gianluca Gentile
Gianluca Gentile
· 7 min di lettura

Il tag <template> è uno degli elementi più sottovalutati di HTML5, eppure rappresenta un meccanismo fondamentale per la creazione di contenuti riutilizzabili e dinamici. A differenza di tutti gli altri elementi HTML, il contenuto di un template non viene renderizzato dal browser, non viene eseguito e non è visibile nella pagina fino a quando non viene esplicitamente attivato tramite JavaScript. Questa caratteristica unica lo rende uno strumento prezioso per lo sviluppo di interfacce web moderne e, in combinazione con i Web Components, per la creazione di componenti HTML personalizzati.

Come Funziona il Tag Template

L’elemento <template> definisce un frammento di markup HTML che il browser parsa ma non renderizza. Il contenuto all’interno del template è quello che la specifica definisce “inerte” (inert): le immagini non vengono scaricate, gli script non vengono eseguiti, i fogli di stile non vengono applicati, gli elementi form non vengono inviati e i media non vengono riprodotti. Il browser prepara la struttura DOM del contenuto, rendendola pronta per essere clonata e utilizzata quando necessario.

Questa inerzia è la caratteristica chiave che distingue il template da approcci alternativi come nascondere elementi con display:none (che vengono comunque renderizzati e le cui risorse vengono scaricate) o inserire markup come stringa in un attributo data-* (che richiede il parsing ogni volta che viene utilizzata).

Il contenuto del template è accessibile tramite la proprietà content, che restituisce un DocumentFragment. Il DocumentFragment è un tipo speciale di nodo DOM che non ha un elemento genitore: quando viene inserito nel documento, vengono inseriti solo i suoi figli, non il fragment stesso. Questa caratteristica rende l’inserimento molto efficiente, poiché avviene in un’unica operazione DOM.

Il template può essere posizionato ovunque nel documento HTML: nel <head>, nel <body>, all’interno di altri elementi. La posizione non influisce sul funzionamento, ma è buona pratica posizionare i template alla fine del body o nell’head per mantenere il markup organizzato e separato dal contenuto visibile.

Clonare e Utilizzare i Template

Per utilizzare il contenuto di un template, il processo standard prevede tre passaggi: selezionare l’elemento template, clonare il suo contenuto e inserire il clone nel documento. La clonazione avviene tramite il metodo cloneNode(true) sulla proprietà content, dove il parametro true indica una clonazione profonda (deep clone) che include tutti gli elementi figli.

Dopo la clonazione, è possibile modificare il contenuto del clone prima dell’inserimento. Si possono aggiornare testi, cambiare attributi, aggiungere event listener e personalizzare il markup in qualsiasi modo. Questa fase di personalizzazione è ciò che rende i template estremamente versatili: un singolo template può generare molte istanze diverse.

Un pattern frequente è l’uso dei template per generare liste dinamiche. Si definisce un template con la struttura di un singolo elemento della lista, poi si itera su un array di dati, clonando il template per ogni elemento, personalizzandolo con i dati specifici e inserendolo nel contenitore della lista. Questo approccio è più performante della costruzione del markup tramite concatenazione di stringhe e innerHTML, poiché il template viene parsato una sola volta.

Per i progetti più complessi, è possibile annidare template all’interno di altri template e clonarli ricorsivamente. Tuttavia, per scenari con molti template e logica di rendering complessa, è generalmente più pratico utilizzare una libreria o un framework che offre un sistema di templating più strutturato.

L’Elemento Slot: Proiezione dei Contenuti

L’elemento <slot> è strettamente legato ai template nel contesto dei Web Components. Uno slot definisce un punto di inserzione nel Shadow DOM dove il contenuto fornito dall’utente del componente (il “light DOM”) viene proiettato. Questa proiezione non sposta fisicamente gli elementi nel Shadow DOM; li mostra nella posizione dello slot mantenendoli nel loro contesto originale.

Lo slot predefinito (default slot) è un elemento <slot> senza attributo name. Riceve tutto il contenuto del light DOM che non è esplicitamente assegnato a uno slot con nome. Se il componente non riceve alcun contenuto, lo slot mostra il suo contenuto di fallback, ovvero qualsiasi markup inserito tra i tag di apertura e chiusura dello slot nel template.

Questo meccanismo di fallback è particolarmente utile per fornire valori predefiniti che vengono automaticamente sostituiti quando l’utente del componente fornisce il proprio contenuto. Ad esempio, un componente card potrebbe avere uno slot per il titolo con un fallback “Titolo predefinito” che viene mostrato solo se nessun titolo viene fornito.

Named Slot: Distribuire Contenuti in Più Punti

I named slot (slot con nome) permettono di definire multiple zone di proiezione all’interno dello stesso componente. Nel template del componente, ogni slot con nome viene dichiarato con un attributo name univoco. Nel light DOM, gli elementi vengono assegnati a uno specifico slot tramite l’attributo slot il cui valore corrisponde al name dello slot di destinazione.

Questa distribuzione multipla è essenziale per componenti strutturati come card, dialog, layout e panel, dove diverse sezioni (header, body, footer, sidebar) devono poter essere personalizzate indipendentemente. Un componente dialog, ad esempio, potrebbe definire slot con nome “header”, “body” e “footer”, permettendo all’utente di personalizzare ciascuna sezione separatamente.

L’evento slotchange viene generato quando il contenuto assegnato a uno slot cambia. Questo evento permette al componente di reagire dinamicamente quando il contenuto proiettato viene modificato, aggiunto o rimosso. Il metodo assignedNodes() sullo slot restituisce l’elenco dei nodi attualmente proiettati, mentre assignedNodes({ flatten: true }) include anche il contenuto di fallback se nessun nodo è proiettato.

È possibile combinare slot con nome e slot predefinito nello stesso componente. Lo slot predefinito raccoglie tutto il contenuto “extra” che non è esplicitamente assegnato a uno slot con nome, offrendo flessibilità sia al creatore del componente che al suo utilizzatore.

Pattern Pratici e Template Literals

Nel JavaScript moderno, i template literals (stringhe delimitate da backtick) offrono un’alternativa complementare al tag <template> per la generazione di markup dinamico. Mentre il tag HTML template è ideale per strutture definite nel markup e riutilizzate più volte, i template literals sono più pratici per la generazione programmatica di HTML all’interno del codice JavaScript.

Un pattern molto diffuso nei Web Components è la definizione del template direttamente nel costruttore della classe, utilizzando template literals per generare la stringa HTML che viene poi assegnata alla proprietà innerHTML del Shadow DOM. Questo approccio è semplice e funzionale, ma meno performante del tag template per componenti istanziati molte volte, poiché la stringa viene ri-parsata ad ogni istanza.

Per il meglio dei due approcci, si può creare un template programmaticamente: si genera un elemento template tramite document.createElement(‘template’), si popola il suo innerHTML con un template literal, e lo si riutilizza clonandolo per ogni istanza del componente. Questa tecnica combina la praticità del template literal con la performance della clonazione.

Librerie come Lit portano questo concetto ancora oltre con il tagged template literal html`…`, che offre rendering efficiente con diffing minimo, binding reattivo dei dati e una sintassi concisa. Per chi sviluppa Web Components professionalmente, Lit rappresenta un eccellente layer di produttività sopra le API native. Per approfondire i Web Components nel loro insieme, consulta il nostro articolo su Custom Elements e Shadow DOM.

Integrazione con i Web Components

Il tag template raggiunge la sua massima espressione quando viene utilizzato in combinazione con Custom Elements e Shadow DOM. In questo contesto, il template definisce la struttura interna del componente, il Shadow DOM la incapsula e protegge dagli stili esterni, e il Custom Element la rende disponibile come un nuovo tag HTML.

Il flusso di creazione tipico prevede: definire un template con la struttura e gli stili del componente; nella classe del Custom Element, nel connectedCallback o nel costruttore, creare il Shadow DOM con attachShadow({mode: ‘open’}); clonare il contenuto del template e inserirlo nel shadow root; aggiungere la logica interattiva tramite event listener e metodi.

Per i componenti che devono aggiornare il proprio contenuto in risposta a cambiamenti di proprietà o attributi, il pattern più semplice è un metodo render() che rigenera il contenuto del Shadow DOM. Per performance ottimali con aggiornamenti frequenti, è preferibile aggiornare solo le parti del DOM che sono effettivamente cambiate, anziché rigenerare l’intero contenuto.

Il tag template in HTML è uno strumento nativo potente che, combinato con le altre tecnologie dei Web Components, permette di creare componenti riutilizzabili, incapsulati e performanti senza dipendenze esterne. Padroneggiare questi strumenti nativi è un investimento che ripaga in termini di longevità, interoperabilità e comprensione profonda della piattaforma web.

Hai bisogno di aiuto con la creazione di componenti web riutilizzabili? G Tech Group offre servizi di sviluppo web professionale e consulenza tecnica sulle architetture frontend. Contattaci a su*****@********up.it o via WhatsApp al 0465 84 62 45.

#sviluppo web