Calling an imported API at runtime in Astro
Astro is a web framework that I like for a lot of reasons, but in particular I like that it runs as little JavaScript as possible (at runtime) by default. When I say “at runtime” I mean as the page is run in the browser, not when your site is built (I’m not going to get into the difference in this post as much, but you’ll see why it matters in a sec).
Anyway, the lack of JavaScript at runtime makes for some really quick, lightweight sites that have a lot of power behind them, but sometimes you want to use some good ol’ scripts.
An Astro component has some frontmatter at the top, kind of like Markdown, where you can import different components and scripts, and then a JSX-like syntax below:
// index.astro
---
import BaseLayout from "./BaseLayout.astro";
let userName = "pretend I'm calling a function or something here";
---
<BaseLayout>
<h1>Hello, {userName ? userName : "world"}!</h1>
</BaseLayout>
When you want to run a script on this page, you could import a component, or just add some <script>
tags to handle it.
But, what if you want to import an API?
// index.astro
---
import BaseLayout from "./BaseLayout.astro";
let userName = "pretend I'm calling a function or something here";
import api from "whatever";
---
<script>
const res = await api(); // api is not defined
</script>
<BaseLayout>
<h1>Hello, {userName ? userName : "world"}!</h1>
</BaseLayout>
Unfortunately, this won’t work! Because the frontmatter imports and the script is called at different points, the api
function there is considered undefined
when you call it.
But, have no fear, this is actually a really quick fix:
// index.astro
---
import BaseLayout from "./BaseLayout.astro";
let userName = "pretend I'm calling a function or something here";
---
<script>
import api from "whatever";
const res = await api(); // api IS defined!
</script>
<BaseLayout>
<h1>Hello, {userName ? userName : "world"}!</h1>
</BaseLayout>
You just have to import your API at the <script>
level, and you’re golden!
Did I write an entire blog post for a one-line fix? Yes.
I keep forgetting this is a thing and I figure a blog will help me actually remember this when I inevitably run into it again. Classic.
Happy trails!