{{titulo}}
{{resumo}}
Busca dados JSON e renderiza numa lista usando um template HTML com {{variáveis}}.
Carrega conteúdo dinâmico (posts, produtos, comentários) de uma API e injeta na página usando um <template> — sem escrever o HTML de cada item manualmente em JS.
Interpola {{campo}} tanto em texto quanto em atributos do template. Suporta três gatilhos: carrega ao aparecer na página (load), ao clicar num botão (click), ou ao entrar na viewport (visible) — bom pra scroll infinito controlado.
{{titulo}}
{{resumo}}
<div sw-content="../assets/demo-posts.json">
<template>
<article class="demo-box demo-mb"><p class="demo-box-title">{{titulo}}</p><p class="demo-box-sub">{{resumo}}</p></article>
</template>
</div>
{{titulo}}
{{resumo}}
<button id="btn-carregar" type="button" class="sw-btn">Carregar posts</button>
<div sw-content="/api/posts" sw-content-trigger="click" sw-content-btn="#btn-carregar">
<template><article>{{titulo}}</article></template>
</div>
O bloco abaixo só busca o JSON quando entra na tela (IntersectionObserver) — role até ele aparecer.
{{titulo}}
{{resumo}}
<div sw-content="/api/posts" sw-content-trigger="visible">
<template><article>{{titulo}}</article></template>
</div>
Lista vazia (JSON real, array [])
Resposta inválida (falha real, sem 404 automático)
<div sw-content="/api/posts"
sw-content-empty="Nenhum post publicado ainda."
sw-content-err="Não foi possível carregar os posts.">
<template><article>{{titulo}}</article></template>
</div>
Com sw-content-paginate, o módulo injeta sozinho os botões ← Anterior/Próxima → quando a resposta traz pagina/paginas — precisa de um backend real que entenda ?page=N, por isso aqui fica só o código de referência (não dá pra simular isso com um arquivo estático).
<div sw-content="/api/posts?limit=10" sw-content-paginate>
<template>
<article>{{titulo}}</article>
</template>
</div>
Formato esperado na resposta:
{
"dados": [ { "titulo": "Post A" } ],
"total": 42,
"pagina": 1,
"paginas": 5
}{{titulo}}
{{resumo}}
Bloco 1
Bloco 2 — mesmo template
<template id="card-post">
<article>{{titulo}}</article>
</template>
<div sw-content="/api/posts?limit=3" sw-content-tmpl="#card-post"></div>
<div sw-content="/api/posts?status=A&limit=6" sw-content-tmpl="#card-post"></div>
// Recarregar bloco via JS
const el = document.querySelector('[sw-content]');
SW.Content.load(el);
// Recarregar ao trocar um filtro
document.querySelector('#filtro').addEventListener('change', (e) => {
el.setAttribute('sw-content', '/api/posts?tipo=' + e.target.value);
SW.Content.load(el);
});
// Escutar depois de renderizar
el.addEventListener('sw:content:loaded', (e) => {
console.log('Dados:', e.detail.dados);
});sw-contentsw-content-tmpl<template> (padrão: procura um <template> dentro do próprio elemento)sw-content-triggersw-content-paginatepagina/paginas na resposta)sw-content-empty / sw-content-errNenhum.
sw:content:loadedSW.Content.load(el){dados:[...]}/{data:[...]}) — não interpreta HTML.sw-content-paginate) precisa de um backend real que leia ?page=N — não dá pra demonstrar ao vivo com um arquivo JSON estático (por isso o exemplo 5 é só código de referência, os outros 6 são ao vivo de verdade).