Carregamento de dados
Exporta uma função data() e o resultado aparece como ctx.data na tua função de renderização. Corre na compilação e, no servidor de desenvolvimento, a cada pedido.
export async function data({ params, dev }) {
const res = await fetch(`https://api.example.com/posts/${params.slug}`)
return await res.json()
}
export default ({ data }) => `
<html><body>
<h1>${data.title}</h1>
${data.body}
</body></html>
`import { html, body, h1 } from 'javascript-to-html'
export async function data({ params, dev }) {
const res = await fetch(`https://api.example.com/posts/${params.slug}`)
return await res.json()
}
export default ({ data }) =>
html(
body(
h1(data.title),
data.body,
),
)export async function data({ params, dev }) {
const res = await fetch(`https://api.example.com/posts/${params.slug}`)
return await res.json()
}
export default function Post({ data }) {
return (
<html>
<body>
<h1>{data.title}</h1>
<div dangerouslySetInnerHTML={{ __html: data.body }} />
</body>
</html>
)
}fetchWithCache
A gerar muitas páginas a partir da mesma API? Importa fetchWithCache do sitelo:
import { fetchWithCache } from 'sitelo'
export async function data({ params }) {
const res = await fetchWithCache(
`https://api.example.com/posts/${params.slug}`,
{ /* opções normais do fetch */ },
{ maxAge: 3600 }
)
return { post: await res.json() }
}Opções
maxAge— TTL da cache em segundos (por omissão3600)cacheKey— chave própria (por omissão: hash do URL + método + cabeçalhos + corpo)forceRefresh— ignora a cachecache—'auto'|'memory'|'fs'|'none'
Modos de cache
auto(por omissão) — memória em desenvolvimento, sistema de ficheiros nas compilações de produçãomemory— no processo, esvazia-se quando o processo terminafs— persistido emnode_modules/.cache/none— vai sempre buscar de novo
Por omissão só os pedidos GET são guardados em cache (passa um cacheKey para guardar outros métodos). Respostas de erro nunca são guardadas.
Ficheiros JSON locais
Sem API? Mantém o conteúdo no repositório em JSON e lê-o com sitelo/data.
data/
├─ site.json
└─ posts/
├─ hello-world.json
└─ why-static.jsonimport { readJsonCollection } from 'sitelo/data'
const posts = () => readJsonCollection('data/posts', { sort: '-date' })
export async function generateStaticParams() {
return (await posts()).map((post) => ({ slug: post.slug }))
}
export async function data({ params }) {
return (await posts()).find((post) => post.slug === params.slug)
}
export default ({ data }) => `
<html><body>
<h1>${data.title}</h1>
<time datetime="${data.date}">${data.date}</time>
${data.body}
</body></html>
`Os caminhos relativos resolvem a partir da raiz do projeto, por isso data/posts significa o mesmo de onde quer que corras a CLI. readJson devolve um ficheiro já analisado; readJsonCollection devolve um array de entradas, cada uma com slug — a partir de uma pasta de ficheiros .json (um por entrada, slug tirado do nome do ficheiro) ou de um único ficheiro com um array de entradas ou um objeto indexado por slug.
// data/posts/hello-world.json -> { slug: 'hello-world', ... }
await readJsonCollection('data/posts')
// data/posts.json: [{ "slug": "hello-world", ... }]
// data/posts.json: { "hello-world": { ... } }
await readJsonCollection('data/posts.json')
// data/site.json
await readJson('data/site.json')Opções de coleção
slug— nome do campo ou função; por omissão o nome do ficheiro, a chave do objeto, ou oslug/idda própria entradasort— nome do campo ('date'ascendente,'-date'descendente) ou uma função de comparaçãorecursive— inclui ficheiros.jsonem subpastas, com o caminho como slugroot— pasta a partir da qual os caminhos relativos resolvemcache—'auto'|'memory'|'none'
As leituras são memorizadas por ficheiro, por isso um build de 500 páginas analisa cada ficheiro uma só vez. O servidor de desenvolvimento verifica a mtime e recarrega o browser quando muda um ficheiro JSON que alguma página leu. Slugs duplicados, ficheiros em falta e JSON inválido falham o build, cada um identificado pelo caminho.