Daten laden
Exportiere eine data()-Funktion, und ihr Ergebnis steht als ctx.data in deiner Render-Funktion bereit. Sie läuft zur Build-Zeit und im Entwicklungsserver bei jeder Anfrage.
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
Du baust viele Seiten gegen dieselbe API? Importiere fetchWithCache aus sitelo:
import { fetchWithCache } from 'sitelo'
export async function data({ params }) {
const res = await fetchWithCache(
`https://api.example.com/posts/${params.slug}`,
{ /* übliche fetch-Optionen */ },
{ maxAge: 3600 }
)
return { post: await res.json() }
}Optionen
maxAge— Cache-Lebensdauer in Sekunden (Standard3600)cacheKey— eigener Schlüssel (Standard: Hash aus URL + Methode + Headern + Body)forceRefresh— umgeht den Cachecache—'auto'|'memory'|'fs'|'none'
Cache-Modi
auto(Standard) — Arbeitsspeicher in der Entwicklung, Dateisystem bei Produktions-Buildsmemory— im Prozess, wird beim Beenden des Prozesses verworfenfs— persistiert unternode_modules/.cache/none— fragt immer neu an
Standardmäßig werden nur GET-Anfragen zwischengespeichert (übergib einen cacheKey, um andere Methoden zu cachen). Fehlerantworten werden nie zwischengespeichert.
Lokale JSON-Dateien
Keine API? Halte die Inhalte als JSON im Repository und lies sie mit 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>
`Relative Pfade werden vom Projektstamm aus aufgelöst, data/posts bedeutet also immer dasselbe, egal von wo aus du die CLI startest. readJson liefert eine geparste Datei; readJsonCollection liefert ein Array von Einträgen, jeder mit slug — aus einem Verzeichnis von .json-Dateien (eine pro Eintrag, Slug aus dem Dateinamen) oder aus einer einzelnen Datei mit einem Array von Einträgen oder einem nach Slug indizierten Objekt.
// 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')Optionen für Sammlungen
slug— Feldname oder Funktion; Standard ist der Dateiname, der Objektschlüssel oder der eigeneslug/iddes Eintragssort— Feldname ('date'aufsteigend,'-date'absteigend) oder eine Vergleichsfunktionrecursive—.json-Dateien in Unterverzeichnissen einbeziehen, mit ihrem Pfad als Slugroot— Verzeichnis, von dem aus relative Pfade aufgelöst werdencache—'auto'|'memory'|'none'
Lesevorgänge werden pro Datei gemerkt, ein Build mit 500 Seiten parst jede Datei also nur einmal. Der Dev-Server prüft stattdessen die mtime und lädt die Seite neu, sobald sich eine gelesene JSON-Datei ändert. Doppelte Slugs, fehlende Dateien und fehlerhaftes JSON lassen den Build fehlschlagen — jeweils mit Pfadangabe.