Chargement de données
Exportez une fonction data() et son résultat apparaît comme ctx.data dans votre fonction de rendu. Elle s’exécute au build, et à chaque requête dans le serveur de développement.
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
Vous générez de nombreuses pages depuis la même API ? Importez fetchWithCache depuis sitelo :
import { fetchWithCache } from 'sitelo'
export async function data({ params }) {
const res = await fetchWithCache(
`https://api.example.com/posts/${params.slug}`,
{ /* options fetch standard */ },
{ maxAge: 3600 }
)
return { post: await res.json() }
}Options
maxAge— durée de vie du cache en secondes (par défaut3600)cacheKey— clé personnalisée (par défaut : hachage de l’URL + méthode + en-têtes + corps)forceRefresh— contourne le cachecache—'auto'|'memory'|'fs'|'none'
Modes de cache
auto(par défaut) — mémoire en développement, système de fichiers pour les builds de productionmemory— dans le processus, vidé à la fin de celui-cifs— persisté dansnode_modules/.cache/none— récupère toujours
Seules les requêtes GET sont mises en cache par défaut (passez un cacheKey pour mettre en cache d’autres méthodes). Les réponses en erreur ne sont jamais mises en cache.
Fichiers JSON locaux
Pas d’API ? Gardez le contenu dans le dépôt en JSON et lisez-le avec 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>
`Les chemins relatifs sont résolus depuis la racine du projet : data/posts désigne la même chose d’où que vous lanciez la CLI. readJson renvoie un fichier analysé ; readJsonCollection renvoie un tableau d’entrées, chacune avec un slug — depuis un dossier de fichiers .json (un par entrée, slug tiré du nom de fichier) ou depuis un seul fichier contenant un tableau d’entrées ou un objet indexé par 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')Options de collection
slug— nom de champ ou fonction ; par défaut le nom de fichier, la clé de l’objet, ou leslug/idde l’entréesort— nom de champ ('date'croissant,'-date'décroissant) ou une fonction de comparaisonrecursive— inclure les fichiers.jsondes sous-dossiers, dont le chemin sert de slugroot— dossier depuis lequel les chemins relatifs sont résoluscache—'auto'|'memory'|'none'
Les lectures sont mémorisées par fichier : un build de 500 pages n’analyse chaque fichier qu’une fois. Le serveur de développement vérifie la mtime et recharge le navigateur dès qu’un fichier JSON lu par une page change. Slugs en double, fichiers manquants et JSON invalide font échouer le build, chacun avec son chemin.