Internal preview of fragments served by this service. Not indexed.
Ogni fragment è esposto come HTML statico raggiungibile via URL pubblico (vedi anteprime sotto). Sono supportate due modalità di integrazione.
Il consumer scarica l'HTML del fragment dal proprio backend e lo include direttamente nella pagina. È la modalità preferita perché:
Esempio Node / Express:
// build-time o request-time, con cache opportuna
const res = await fetch('https://fragments.example.com/footer/giornaledibrescia/prod/v1.html');
const html = await res.text();
// poi inietti `html` nel template della tua pagina (SSR, Astro, Next, ecc.)
Esempio nginx SSI (con ssi on; attivo sul server):
<!--# include virtual="/proxy/footer/giornaledibrescia/prod/v1.html" -->
Gli stili del fragment sono inline e prefissati con .gdb-footer,
quindi non collidono con il CSS della pagina ospite.
Da usare quando il fetch server-side non è praticabile (es. integrazioni
cross-domain senza backend). Il fragment espone un protocollo
postMessage per comunicare al parent l'altezza reale del
contenuto, così l'iframe può adattarsi dinamicamente.
<iframe
src="https://fragments.example.com/footer/giornaledibrescia/prod/v1.html"
data-fragment-source="footer:giornaledibrescia:v1"
width="100%"
height="0"
style="border: 0; display: block;"
title="Footer Giornale di Brescia"
></iframe>
Il fragment invia messaggi { type: 'fragment:resize', source, height }
al parent ogni volta che l'altezza del contenuto cambia (load iniziale,
cambio viewport, contenuto dinamico). Il parent ascolta e aggiorna
l'altezza dell'iframe corrispondente:
<script>
window.addEventListener('message', (event) => {
const data = event.data;
if (!data || data.type !== 'fragment:resize') return;
// valida l'origin in produzione
// if (event.origin !== 'https://fragments.example.com') return;
const iframes = document.querySelectorAll(
`iframe[data-fragment-source="${data.source}"]`
);
for (const iframe of iframes) {
// event.source distingue iframe multipli con lo stesso source
if (iframe.contentWindow === event.source) {
iframe.height = String(data.height);
return;
}
}
});
</script>
Per evitare race condition (l'iframe può finire di caricare e spedire
il primo fragment:resize prima che il listener del parent
sia attaccato), il parent può inviare un ping
{ type: 'fragment:ready' } al
contentWindow dell'iframe quando è pronto a ricevere. Il
fragment risponde con un re-send forzato dell'altezza corrente:
<script>
document.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll('iframe[data-fragment-source]').forEach((iframe) => {
const ping = () => iframe.contentWindow?.postMessage(
{ type: 'fragment:ready' },
'*' // o l'origin del fragment in produzione
);
iframe.addEventListener('load', ping);
ping();
});
});
</script>
Lo stesso ping è utile per forzare un resize sync dopo cambi di stato
lato parent (es. iframe rivelato dopo un display:none,
mount tardivo, ecc.).
event.origin
prima di fidarsi del messaggio, restringendo all'origin del servizio
fragments.
'*' nel postMessage
del ping con l'origin del fragment per evitare leak verso altri
contesti.
dev — /footer/giornaledibrescia/dev/v1.html staging — /footer/giornaledibrescia/staging/v1.html prod — /footer/giornaledibrescia/prod/v1.html