A First Look at Astro
Published:
Astro is a web framework that supports the Islands Architecture and includes integrations for React, Svelte, Vue, Solid, and many more.
Outline
All of this project’s code can be found in the First Look monorepo on my GitHub.
Introduction
Astro is an open source web framework influenced by the Islands Architecture. It was created by Fred K. Schott, Matthew Phillips, Nate Moore, and Drew Powers as an outgrowth of the work being done simultaneously on Snowpack and Skypack.
It supports a variety of UI integrations including React, Svelte, Vue, Solid, and many more. The framework deserves a fair amount of credit for bringing partial hydration and the concept of “Islands of Interactivity” to the mainstream web development conversation.
Partial Hydration
I have an entirely separate, lengthy article about this, but here’s the summary. The conversation had been present but on the fringes for well over a decade. The first framework that fully supported these techniques, Marko, was created in 2014 but remained the odd duck out until around 2019.
However, in the last 2 years there has been an influx of frameworks drawing on similar motivations and prior art including Slinkity, Elder.js, îles, and Qwik. Fred K. Schott describes the architecture and goals of Astro in Introducing Astro: Ship Less JavaScript (June 8, 2021):
Astro works a lot like a static site generator. If you have ever used Eleventy, Hugo, or Jekyll (or even a server-side web framework like Rails, Laravel, or Django) then you should feel right at home with Astro.
In Astro, you compose your website using UI components from your favorite JavaScript web framework (React, Svelte, Vue, etc). Astro renders your entire site to static HTML during the build. The result is a fully static website with all JavaScript removed from the final page.
While there are plenty of frameworks based on React, Vue, and Svelte that let you render components to static HTML during build time, if you want to hydrate these projects on the client then you have to ship an entire bundle of dependencies along with the static HTML. Astro, on the other hand, includes the ability to load just a single component and its dependencies where that component is needed.
Client Directives
Astro includes five client:*
directives to hydrate components on the client at runtime. A directive is a component attribute that tells Astro how your component should be rendered.
Directive | Description |
---|---|
<Component client:load /> | Hydrates the component on page load. |
<Component client:idle /> | Hydrates the component as soon as main thread is free. |
<Component client:visible /> | Hydrates the component as soon as the element enters the viewport. |
<Component client:media={QUERY} /> | Hydrates the component as soon as the browser matches the given media query. |
<Component client:only /> | Hydrates the component at page load, similar to client:load . The component will be skipped at build time. |
Create Project
This tutorial will build up an Astro project from scratch instead of using any of the starter templates because I believe that is a better way to learn how a framework works, but the templates are really fantastic.
Start by creating a new directory for your project and initializing a package.json
file.
Install Astro Dependency
Install the astro
dependency and create .gitignore
file.
Add CLI Commands
Add the following scripts to package.json
.
All commands are run from the root of the project.
npm run dev
andnpm start
both start a local development server onlocalhost:4321
.npm run build
builds a production site to./dist
.npm run preview
previews the build locally before deploying.
Create an Astro Page
Astro looks for .astro
or .md
files in the src/pages
directory. Each page is exposed as a route based on its file name. Static assets such as images can be placed in the public
directory.
Inside the src/pages
directory we created an index.astro
file.
Start Development Server
Open localhost:4321 to see the home page.
Add Styling
I’ll include Water.css in the head
of index.html
for some nice looking CSS defaults.
Create a Markdown Page
The next page example will use Markdown and render completely statically.
Write some Markdown in about.md
.
Open localhost:4321/about to see the home page.
Add Components
We’ll create a directory called components
inside src
to hold any Astro/React/Vue/Svelte/Preact components. Then we will create extra directories that will hold .astro
, .jsx
, and .svelte
files for Markdown, React, and Svelte components respectively.
Create a React Component
To configure Astro, add an astro.config.mjs
file and install the necessary React dependencies by running the following command:
This installs @astrojs/react
, react-dom@^18.0.0
, and react@^18.0.0
. It also adds the following code to astro.config.mjs
to enable the React renderer and provide support for React JSX components.
We’ll create a react
directory with a HelloReact.jsx
component inside.
It’s a React component so you’re contractually obligated to make it a counter with useState
that is triggered with an onClick
event handler on a <button>
.
Importing the HelloReact
component is much like the HelloMarkdown
component. However, this time we’re including someProps
in the front matter to set the initial count
to 0
.
We also include client:visible
to hydrate the component as soon as the element enters the viewport.
Create a Svelte Component
Add svelte()
to integrations
in astro.config.mjs
to enable the Svelte renderer and provide support for Svelte components.
This also installs @astrojs/svelte
and svelte@^3.46.4
.
As with React, create a svelte
directory and HelloSvelte.svelte
file.
Our Svelte component will contain the same functionality as our React component.
Import HelloSvelte
and set it to client:visible
.
Create a Vue Component
Add vue()
to integrations
in astro.config.mjs
to enable the Vue renderer.
This also install @astrojs/vue
and vue@^3.2.30
.
You know the drill.
Our Vue component will contain the same functionality as our React and Svelte components.
Import HelloVue
and set it to client:visible
.
Add GraphQL Data Fetching
Import HelloGraphQL
.
Deploy to Netlify
The Astro docs contain over a dozen different deployment options. We will deploy our project to Netlify. Create a netlify.toml
file for our build configuration.
Add npm run build
for the build command and dist
for the publish directory.
Here is our final project structure.
Create a GitHub Repository
Initialize a git repo and push to a GitHub repository.
Connect GitHub Repository to Netlify
Connect your GitHub repository to Netlify.
Go to “Site settings,” to give yourself a custom domain name.
Open ajcwebdev-astro.netlify.app
to see the deployed site.