Conteúdo via JSON Componentes
Busca uma lista em JSON e monta os cartões na tela sozinho — você escreve um modelo com {{campo}} e ele repete para cada item.
O que é
Serve para mostrar na página uma lista que vem de um endereço (a sua API, um arquivo .json): produtos, vantagens, depoimentos, cidades atendidas. Você escreve um cartão de exemplo dentro de um <template>, marcando com {{campo}} onde entra cada informação, e o SWCore repete esse cartão uma vez para cada item da lista. Também preenche as opções de um <select> com a mesma lista.
Quando a página abre (ou quando a pessoa clica, ou quando o bloco aparece na tela — você escolhe), ele busca o endereço, lê a lista e troca cada {{campo}} pelo valor daquele item. Aceita a lista pura ([ … ]) ou dentro de dados ou data ({ "dados": [ … ] }). Se a lista vier vazia, mostra a mensagem de "vazio"; se a busca falhar, mostra a mensagem de erro. Não precisa escrever JavaScript.
Quando usar
- Lista que muda sem mexer no HTML: vantagens, planos, unidades da loja, equipe — você atualiza o JSON e a página acompanha.
- <select> de categorias/cidades que vem do banco:
sw-content-select. - Carregar só quando precisar:
sw-content-trigger="visible"(ao aparecer na tela) ou"click"(num botão "Ver mais"). - Se o seu servidor devolve HTML pronto em vez de JSON, o componente certo é o AJAX declarativo.
Comece aqui
-
1
Coloque o SWCore na página (CSS no
<head>, JS no fim do<body>).<link rel="stylesheet" href="https://swcore.sanweb.com.br/dist/2.1.0/swcore.min.css"> <!-- fim do <body> --> <script src="https://swcore.sanweb.com.br/dist/2.1.0/swcore.min.js"></script> -
2
Tenha um endereço que devolva uma lista em JSON. Este é o arquivo usado nos exemplos desta página:
[ { "id": "1", "titulo": "Entrega em 24h", "resumo": "Pedidos aprovados até as 15h saem no mesmo dia.", "autor": "Logística" }, { "id": "2", "titulo": "Troca sem burocracia", "resumo": "Sete dias para trocar, sem precisar justificar.", "autor": "Atendimento" } ] -
3
Escreva o bloco com
sw-content="endereço"e, dentro, um<template>com o cartão de exemplo usando{{campo}}.{{titulo}}{{resumo}}<div sw-content="/api/vantagens.json"> <template> <div class="bg-sur bd p-m r-m mb-3"> <strong>{{titulo}}</strong> <div class="t-p op-8">{{resumo}}</div> </div> </template> </div>
Todas as variações
Cada quadro abaixo é o componente de verdade, rodando. O código embaixo é exatamente o que está no quadro: copie e cole.
1. Onde os dados aparecem
O mesmo arquivo JSON, desenhado de jeitos diferentes. Tudo que está dentro do <template> é repetido para cada item.
<div sw-content="../../assets/demo-content.json">
<template>
<div class="bg-sur bd p-m r-m mb-3">
<strong>{{titulo}}</strong>
<div class="t-p op-8">{{resumo}}</div>
</div>
</template>
</div>
- {{titulo}} — {{autor}}
<ul sw-content="../../assets/demo-content.json">
<template>
<li><a href="#vantagem-{{id}}" title="{{resumo}}" class="Tsw-link">{{titulo}}</a> — <span class="op-7">{{autor}}</span></li>
</template>
</ul>
<template id="tmpl-vantagem-demo">
<div class="flx alc gap-3 mb-3"><i class="swi-check t-pri"></i> {{titulo}}</div>
</template>
<div sw-content="../../assets/demo-content.json" sw-content-tmpl="#tmpl-vantagem-demo"></div>
2. Preenchendo um <select>
Num <select> não precisa de <template>: diga qual campo vira o texto da opção (sw-content-select) e, se quiser, qual vira o valor enviado no formulário (sw-content-value).
<select sw-inp sw-content="../../assets/demo-content.json" sw-content-select="titulo" sw-content-value="id" aria-label="Vantagem"></select>
<select sw-inp sw-content="../../assets/demo-content.json" sw-content-select="autor" aria-label="Setor"></select>
3. Quando buscar
Por padrão ele busca assim que a página abre. Dá para esperar a pessoa pedir ou o bloco aparecer na tela.
<button type="button" sw-btn="out p" id="ct-demo-btn">Ver vantagens</button>
<div sw-content="../../assets/demo-content.json" sw-content-trigger="click" sw-content-btn="#ct-demo-btn" class="mt-3">
<template>
<div class="flx alc gap-3 mb-3"><i class="swi-check t-suc"></i> {{titulo}}</div>
</template>
</div>
<div sw-content="../../assets/demo-content.json" sw-content-trigger="visible">
<template>
<div class="flx alc gap-3 mb-3"><i class="swi-star t-pri"></i> {{titulo}} <span class="op-7">({{autor}})</span></div>
</template>
</div>
4. Formatos de resposta e mensagens
Nestes quadros a "resposta da API" está escrita direto no endereço (data:application/json,…) só para simular cada caso sem internet. No seu site, é o endereço da sua API.
<div sw-content='data:application/json,{"dados":[{"nome":"Ana","cargo":"Designer"},{"nome":"Bruno","cargo":"Programador"}]}'>
<template>
<div class="mb-3"><strong>{{nome}}</strong> — {{cargo}}</div>
</template>
</div>
<div sw-content="data:application/json,[]" sw-content-empty="Nenhum pedido por aqui ainda.">
<template><div>{{numero}}</div></template>
</div>
<div sw-content="data:application/json,resposta-quebrada" sw-content-err="Não foi possível carregar agora. Tente de novo.">
<template><div>{{titulo}}</div></template>
</div>
Tabela de opções
| Palavra | O que faz | Exemplo |
|---|---|---|
| No bloco | ||
sw-content | Endereço que devolve a lista em JSON. Obrigatório. | sw-content="/api/produtos.json" |
sw-content-tmpl | Onde está o modelo, quando ele fica fora do bloco (um <template id="…">). Sem ele, usa o <template> de dentro. | sw-content-tmpl="#cartao" |
sw-content-trigger | Quando buscar: load (padrão, ao abrir) · click · visible (ao aparecer na tela). | sw-content-trigger="visible" |
sw-content-btn | Com trigger="click": qual botão dispara a busca. Sem ele, é o primeiro elemento da página com sw-content-load. | sw-content-btn="#ver-mais" |
sw-content-load | Marca o botão que dispara a busca quando não se usa sw-content-btn. | <button sw-content-load> |
sw-content-empty | Texto mostrado quando a lista vem vazia. Sem ele, fica em branco. | sw-content-empty="Nada por aqui." |
sw-content-err | Texto mostrado quando a busca falha. Padrão: "Erro ao carregar conteúdo." | sw-content-err="Tente mais tarde." |
sw-content-paginate | Pede a lista por páginas: acrescenta ?page=1, ?page=2… no endereço e mostra botões Anterior/Próxima. | sw-content-paginate |
| No <select> | ||
sw-content-select | Campo do item que vira o texto de cada opção. | sw-content-select="nome" |
sw-content-value | Campo que vira o valor enviado. Sem ele, o valor é o próprio texto. | sw-content-value="id" |
| No modelo | ||
{{campo}} | Onde entra o valor daquele campo. Vale no texto e dentro de atributos. Só nome simples (letras, números e _). | <h3>{{titulo}}</h3> |
| Formato da resposta | ||
[ … ] | Lista pura. | [{"titulo":"A"},{"titulo":"B"}] |
{ "dados": [ … ] } | Lista dentro de dados (ou data). | {"dados":[…]} |
pagina / paginas | Com sw-content-paginate: página atual e total. Também aceita page/pages e current_page/last_page. | {"dados":[…],"pagina":1,"paginas":5} |
Receitas prontas — usos reais
Situações que aparecem em quase todo site. Copie a que servir.
<div sw-content="/api/vantagens.json" sw-content-empty="Em breve novidades.">
<template>
<div class="flx gap-3 mb-4">
<i class="swi-check t-suc"></i>
<div><strong>{{titulo}}</strong><div class="t-p op-8">{{resumo}}</div></div>
</div>
</template>
</div>
<label for="cidade">Cidade</label>
<select sw-inp id="cidade" name="cidade"
sw-content="/api/cidades.json"
sw-content-select="nome"
sw-content-value="id"></select>
<div sw-content="/api/depoimentos.json" sw-content-trigger="click" sw-content-btn="#ver-mais">
<template>
<div class="bg-sur bd p-m r-m mb-3">{{titulo}}</div>
</template>
</div>
<button type="button" sw-btn="pri p" id="ver-mais">Ver mais depoimentos</button>
<!-- o SWCore chama /api/posts?page=1, ?page=2… e desenha os botões Anterior/Próxima -->
<div sw-content="/api/posts" sw-content-paginate>
<template>
<article class="bd p-m r-m mb-3">
<h3>{{titulo}}</h3>
<p>{{resumo}}</p>
</article>
</template>
</div>
<!-- a API responde assim: -->
<!-- { "dados": [ … ], "pagina": 1, "paginas": 5 } -->
<script>
// recarregar um bloco sw-content (ex.: depois de salvar algo)
SW.Content.load(document.querySelector('#lista-pedidos'));
// só ler o JSON, sem desenhar nada
SW.Content.fetchJSON('/api/vendas.json').then((dados) => montarGrafico(dados));
// saber quando a lista terminou de aparecer
document.addEventListener('sw:content:loaded', (e) => {
console.log('chegou', e.detail.dados);
});
</script>
Eventos
sw:content:loadeddocument). e.detail.dados traz o JSON recebido.API (JavaScript)
SW.Content.load(elemento)sw-content.SW.Content.fetchJSON(url, { method, headers, body })Precisa de quê
swcore.min.csseswcore.min.js.- Um endereço que devolva JSON. Se for de outro domínio, ele precisa liberar o acesso (CORS).
Cuidados — erros comuns
- Classes de grade no próprio bloco (
class="l l-3") funcionam: cada item vira filho direto do bloco. A paginação e as mensagens de vazio/erro ocupam a linha inteira da grade. - O
{{campo}}precisa ter exatamente o nome do campo no JSON (maiúsculas contam). Campo que não existe vira vazio, sem aviso. - Campo dentro de campo (
{{cliente.nome}}) não funciona: achate o JSON no servidor. - Configure sempre
sw-content-empty: sem ele, lista vazia vira um espaço em branco e a pessoa acha que está carregando. - Não coloque em
{{campo}}de umhrefum valor que o visitante digitou (ele poderia gravar um link perigoso). Dados assim devem ser conferidos no servidor.
O que ele não faz
- O conteúdo é montado no navegador depois que a página abre: o Google pode não ler essa lista. Conteúdo importante para busca deve vir pronto do servidor.
- Não formata valores (moeda, data): o JSON já deve trazer o texto como deve aparecer.

