Data, content, and assets
Load data before rendering
Use top-level await in frontmatter and know whether the work happens during a build or an on-demand request.
An Astro component can wait for data before it renders. Frontmatter supports top-level await, so you fetch first, then you template.
Let’s ask the GitHub API how many stars the Astro repository has:
---
const response = await fetch('https://api.github.com/repos/withastro/astro')
if (!response.ok) {
throw new Error(`GitHub request failed: ${response.status}`)
}
const repo = await response.json()
---
<p>Astro has {repo.stargazers_count} stars on GitHub.</p>
Open the page and you see the number. No spinner, no loading state, no client-side fetch. Astro waited for the response, rendered the paragraph, and sent finished HTML.
View the source. The JSON is not there. The fetch call is not there. Only the paragraph.
When does this run?
This is the question to always ask in Astro. The code runs when the route renders, and that depends on the output mode.
For a static route, the default, it runs during npm run build. The star count is baked into dist/index.html. Visitors get a file. The API could go down for a week and your page would still load in milliseconds. But the number stays frozen until the next build.
For an on-demand route, it runs on the server for every request. The number is always fresh. Now every visitor waits for GitHub, and if GitHub is slow, your page is slow.
Neither is wrong. Ask how stale the page can be. A star count can be a day old. A stock price cannot.
Handle failures on purpose
The response.ok check matters. Without it, a 404 or a 500 gives you response.json() of an error body, and the template renders undefined stars. The build succeeds. You ship a broken page without knowing.
With the check, the build stops with a clear error. For a static site that’s what I want. Better a failed build than a silently empty page.
You will hit this for real with GitHub. Unauthenticated requests are limited to 60 per hour per IP address. Run the dev server, reload a lot, and at some point the page fails with:
Error: GitHub request failed: 403
That’s the rate limit. Wait an hour, or send a token in an Authorization header. The next lesson covers how to do that without leaking the token.
Lesson completed