Fetching data at build time
The frontmatter runs on the server, so it can call external APIs with fetch() and read files directly. In a static site this happens once, during the build: the visitor gets ready HTML with the data, and no API request goes out from their browser.
Calling an API
Suppose the blog has a service with recommended books at https://example.com/api/books.json. Create the page src/pages/books.astro:
---
import BaseLayout from '../layouts/BaseLayout.astro';
const response = await fetch('https://example.com/api/books.json');
const books = await response.json();
---
<BaseLayout title="Books">
<h1>What to read</h1>
<ul>
{books.map((book) => <li>{book.title} by {book.author}</li>)}
</ul>
</BaseLayout>Open /books and a list of books appears. fetch() and await work in the frontmatter the same way as in any async code from the tutorial. In development the request runs every time the page is opened; after npm run build it runs once.
Checking the response
If the API responds with an error, response.json() may fail with an unclear message. It is better to check the status explicitly:
---
const response = await fetch('https://example.com/api/books.json');
if (!response.ok) {
throw new Error(`Books API responded with ${response.status}`);
}
const books = await response.json();
---An error in the frontmatter stops the build, and the terminal shows which page failed and why. That is better than publishing a site with an empty list.
Data from a file
Small data is handy to keep right in the project. Create src/data/links.json:
[
{ "title": "Astro docs", "url": "https://docs.astro.build" },
{ "title": "MDN", "url": "https://developer.mozilla.org" }
]And import it in the frontmatter, for example in src/pages/about.astro:
---
import links from '../data/links.json';
---
<ul>
{links.map((link) => <li><a href={link.url}>{link.title}</a></li>)}
</ul>JSON files are imported as ordinary modules, without fetch(). The page shows a list of two links.
When data goes stale
Data fetched during the build does not update until the site is built again. For rarely changing data that is fine: builds run on a schedule or after a change. If data must be fresh every time the page is opened, you need on-demand rendering, the next lesson.
Common mistake
People put a secret API key right into the frontmatter code and commit it to Git. Even though frontmatter code does not reach the browser, the key ends up in the repository. Keys are kept in a .env file and read through astro:env, as the environment variables lesson shows.