Introduction
Astro is one of the most talked-about web frameworks in recent months. Its premise is quite promising: develop static sites and send zero JavaScript to the client.
We can create reusable Astro components with a JSX-like syntax, allowing us to write JavaScript in the top section of the file:
---
const title = "Hello Astro! 🪐";
const technologies = ["React", "vue", "svelte", "solid.js", "lit"];
---
<h1>{title}</h1>
<section>
<h2>Technologies</h2>
{technologies.map(technology => <p>{technology}</p>)}
</section>This JavaScript executes only when generating the static files for our website. However, we can take advantage of another great feature of this framework: island architecture.
Island Architecture (Astro Islands)
Island architecture or Astro Islands refers to the existence of interactive UI components in a predominantly static HTML page. Multiple islands can coexist on the same page, and each island renders in isolation. The Astro team describes it as:
Think of them as islands in a sea of static, non-interactive HTML.
These UI components can come from different frameworks or libraries — they don't need to be from the same technology. We can mix several, or use whichever we're most comfortable with (React, Svelte, Vue, Preact, Lit, etc.)
Compatible Frameworks and Libraries
We can use components from other frameworks in Astro pages like this:
---
// Example: Use a static React component on the page, without JavaScript.
import MyReactComponent from '../components/MyReactComponent.jsx';
---
<!-- 100% HTML, Zero JavaScript loaded on the page! -->
<MyReactComponent />Client Directives
To decide how to hydrate those components, we can add a series of directives.
---
// Example: Use a dynamic React component on the page.
import MyReactComponent from '../components/MyReactComponent.jsx';
---
<!-- This component is now interactive on the page!
The rest of your site will remain static with zero JS. -->
<MyReactComponent client:load />In this example, the client:load directive is used, indicating that this component should be interactive on the client as soon as possible. Some of the available directives are:
client:idle
Lower priority elements (medium), that don't need to be loaded immediately. Loads and hydrates once the initial page load is complete. This directive may not be compatible with all browsers, in which case the load directive is used.
---
import LoginButton from "./components/LoginButton.jsx"
---
<header>
<!-- Button that opens a Login modal -->
<LoginButton client:idle />
</header>client:visible
Low priority elements, found at the bottom of the page or requiring so many resources that it's preferable not to load them. They only load when they're in the viewport.
---
import Footer from "./components/Footer.jsx"
---
<header>
<!-- Some navigation menu, logo, etc -->
</header>
<main>
<!-- Main page content -->
</main>
<!-- Will load when it's in the viewport -->
<Footer client:visible />client:media
For elements that only need to be loaded on certain screen sizes, using CSS media queries.
---
import HamburgerNav from "./components/HamburgerNav.jsx"
---
<nav>
<!-- Will only load at this screen size -->
<HamburgerNav client:media="(max-width: 768px)" />
</nav>client:only
The element only renders on the client side. You need to specify the correct framework type for it to work correctly.
---
import PaginatedTable from "./components/PaginatedTable.jsx"
---
<section>
<PaginatedTable client:only="react" />
</section>There are more directives available, not just for the client, which can be consulted in the Astro documentation.
Conclusion
From my point of view this framework has enormous potential for generating static pages, such as portfolios, blogs or personal websites, which don't require heavy JavaScript loading. It's also the first agnostic framework — we can use any UI framework in our Astro project, giving us the versatility to reuse or combine other components in our project.
I'm using it to redesign my portfolio and add a section for my blog. I'm sharing the repository with the code here as an example of using this tool.
It has many more things to talk about and explore — it's constantly evolving. Version 3 was recently released with a new feature: compatibility with the ViewTransitions API. These and many other new features deserve their own article to explore in depth.
References
Many of the examples and explanations are based on the Astro documentation: