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.

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,
    ),
  )

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

Modos de cache

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.json
import { 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

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.