Astro is Amazing

What can this static site generation framework do for you?
Monday, May 6, 2024

What is Astro?

Astro is a static site generation framework that allows you to build websites using almost any other frontend framework you want. It’s an amazing way to build websites and webapps without having to worry about the SSR(server side rendering), SSG(server side generation) or SEO(search engine optimization) of your website.

Basically in short it’s biggest strength is that you get to choose your favorite framework and Astro will take care of the SSG or SSR part for you. So say you like Next.js but you’d prefer to use something like Solid.js, you could write your entire app in Svelte and then roll your own SSR and SSG for it. Or you could build it within Astro and let it handle that for you.

Can you use multiple Frameworks as once in Astro?

Yes, you can if you so choose use something like React and Vue at the same time in Astro. Simply run npx astro add react and npx astro add vue create your components in your components folder and then import them into your Astro page like so:

---
import { ReactComponent } from '/components/ReactComponent'
import { VueComponent } from '/components/VueComponent'
---

<ReactComponent />
<VueComponent />

Tadah now you have a React and Vue component on the same page.

What are Astro Client Directives?

Astro client directives are a way to tell Astro how to hydrate UI components on the page. The default directive is not to hydrate the component on the client at all. This is useful for components that don’t need to be interactive or don’t need to be re-rendered on the client.

but let’s look at the different directives you can use:

client:load

This directive tells Astro to load and hydrate the component immediately on client load. This is useful for elements that need to be interactive immediately after the page loads, such as elements above the fold or elements that are part of the page’s initial interactivity.

client:idle

This directive tells Astro to load and hydrate the component when the browser has completed it’s initial load of your page and or fired a requestIdleCallback if the browser does not support the requestIdleCallback the document load event will be used instead.

This is useful for elements that are not critical to the initial interactivity of the page, such as a slider or a carousel as long as it’s not above the fold.

client:visible

This directive tells Astro to load and hydrate the component when it becomes visible in the viewport. This is useful for elements that are not critical to the initial interactivity of the page and are not above the fold.

You can also specify a rootMargin to the directive as such: client:visible={{rootMargin: '100px'}} this will load in and hydrate the component when a specific margin around the component enters the viewport, instead of the component itself. This is especially useful for lazy loading images or other assets and giving your users a perception of a faster loading page thus improving the user experience.

client:media

This directive tells Astro to load and hydrate the component when a specific media query is met. These are basically the same as CSS media queries and can be used to load and hydrate components based on the user’s device or screen size.

for example:

<MobileMenu client:media="(max-width: 768px)" />
<DesktopMenu client:media="(min-width: 769px)" />

The above code will load and hydrate the MobileMenu component when the screen size is less than or equal to 768px and the DesktopMenu component when the screen size is greater than or equal to 769px.

client:only

This directive completely disables server-side rendering for the component and only hydrates the component on the client. It basically works the same as client:load but with the added benefit of not being rendered on the server at all. This is useful for components that are not critical to your SEO or that don’t need to be rendered on the server at all.

You do have to specify the framework of the component you are using in the directive like so: client:only="react" or client:only="svelte". This is because Astro needs to know which framework to use to hydrate the component on the client.

Custom Directives

You can also create your own custom directives for that I’d suggest reading the extensive documentation on Astro addClientDirective

How Does Astro Work?

Astro works by using your target framework to build, render and hydrate your components on the server and then sends the HTML, CSS and JavaScript to the client. Essentially instead of the client having to render the components on the client, Astro does it for you on the server and sends the pre-rendered HTML, CSS and JavaScript to the client. Unless you specify otherwise with the client directives.

If I use client:only does that mean Astro needs to send the entire React or Svelte library to the client?

Yes and no, Astro will only send the parts of the library that are needed to hydrate the component on the client. So if you use client:only with a React component Astro will only send the parts of React that are needed to hydrate the component on the client. This is a huge benefit as it means you can use your favorite framework without having to worry about the size of the library being sent to the client.

When to Use Astro?

Astro is a great choice for building websites and webapps that need to be fast, accessible and SEO friendly. Basically if you want to build something like a blog or a website or webapp where most of your content can be pre-rendered via SSG or SSR then astro is a great choice.

When not to use Astro?

While Astro has it’s strengths it also has it’s weaknesses. If your requirements are to build a complex and interactive webapp that requires a lot of user interaction and real-time updates then Astro might not be the best choice for you. Astro is great for building static websites and webapps but it’s not so great for building complex and interactive webapps.

So say you wanted to build something like a live updating chat app or a sports ticker then Astro might not be the best choice for you.

Is Astro production ready?

Yes Astro has a dedicated team of amazing developers actively working on it, add that to a great and thriving community of Astro enthusiasts and you have a recipe for success. Astro is production ready and is in use by a lot of big name companies such as: Google, NordVPN, ROKT, Microsoft and many more.

So I’d say Astro is a pretty safe bet if you’re worried about it being production ready.

Can Astro be used with React?

Yes Astro can be used with React, in fact you can use almost any frontend framework you want with Astro. Simply run npx astro add react and you’re good to go.

You can also use: Alpine.js, Lit, Preact, Solid, Svelte and Vue.

Does Astro support TypeScript?

Yes Astro does support TypeScript, in fact it has built in support for TypeScript. You can either configure to use typescript when you create your project or add it in later by running hassle free.

Just be sure to ensure that the framework you are using with Astro also supports TypeScript.

Does Astro really ship without JavaScript?

Yes and no, by default if you only write .astro files then yes Astro will ship without any JavaScript except for any JavaScript that you, yourself provide via <script> tags. But if you use a framework like React or Svelte then Astro will ship the JavaScript needed to hydrate the components on the client.

Astro vs. Next.js

Astro and Next.js are both great choices for building websites and webapps but they have their differences. Next.js is a full stack framework that comes with a lot of features out of the box such as: routing, server-side rendering, static site generation, API routes and more. Astro on the other hand is a static site generation framework that allows you to build websites using almost any other frontend framework you want and while it also has file based routing and allows you to do server-side rendering and static site generation it doesn’t have as many features as Next.js out of the box.

Think of Astro as a general purpose toolbox that allows you to build websites and webapps using almost any frontend framework you want and Next.js as a specialized toolbox that exclusively focused on building websites and webapps using React and comes with a lot of cutting edge features out of the box.

Can you use Astro with a CMS?

Yes you can use Astro with a CMS, in fact Astro has built in support for markdown and .mdx files and you can use any headless CMS you want with Astro. Simply create a folder in your project called content and add your markdown or .mdx files to it. You can then easily load and parse them in your Astro pages by using the getCollection function.

Can you share state between different frameworks?

Yes you can and it is awesome. You have two different approaches to share state for two different usecases:

Share State Between Astro Components

For this you can use nanostores simply run npm install nanostores and then import it into your components like so:

import { atom } from 'nanostores'

export const count = atom(0)

The count atom will hold the value of the count state which can then be modified from within any of the components using set on the atom itself i.e: count.set(3)

import { count } from '/stores/count'

<button onClick={() => count.set(count + 1)}>Increment</button>

Easy isn’t it?

Share State Between Different Frameworks

Using nanostores yet again we can then share the state between different frameworks from within Astro islands. For this we do need to install nanostore support for each framework that we are using so let’s assume we are using React and Solid we would need to run

npm install nanostores @nanostores/react
npm install nanostores @nanostores/solid

Now from within our React component we can import the atom from above and use it like so:

import {useStore} from "@nanostores/react"
import { count } from '/stores/count'

export default function ReactComponent() {
  const value = useStore(count)
  return <div>{value}</div>
}

And within our Solid component:

import {useStore} from "@nanostores/solid"
import { count } from '/stores/count'

export default function SolidComponent() {
  const $value = useStore(count);
  return <div>{$value}</div>
}

And that’s really all there is to it once again we can modify the state from within any of the components using set on the atom itself i.e: value.set(3)

What are Astro Islands?

Astro pioneered the concept of frontend Islands, basically astro islands are a way to build components that then partially or selectively hydrated on the client. So in essence ship HTML and CSS where you can and then hydrate the components of the page in a way that is most beneficial to the user. Instead of the traditional SPA way of shipping everything to the client and rendering it there as a monolith.

So in Astro an island may be something like header or menu component that is can run in isolation from the rest of the components on the page. You can ship nearly the entire page as pure HTML and CSS while the header or menu components are hydrated on the client as needed and specified by the client directives.

Does Astro support server-side rendering?

Yes astro does support SSR and SSG(by default) out of the box.

Does Astro support lazy loading?

Yes Astro has built in support for lazy loading images and other assets. Images can be lazily loaded using the loading="lazy" attribute on the <img> tag. This will tell the browser to only load the image when it is in the viewport. And Scripts can be lazily loaded using the defer attribute on the <script> tag. This will tell the browser to only load the script after the page has loaded.

However with Astro we can optimize scripts and script loading even further using directives.

Astro optimize script loading

By default astro will load and bundle all your scripts and styles no matter where you place them in your project, unless you specify otherwise using one of the Script or Style directives

is:global

As the name suggests this opts the Style out of the astro automatic bundling process and makes it into a global style. This is useful for styles that are used across multiple components or pages and don’t need to be bundled with the component or page.

is:inline

This directive will tell astro to not bundle the script or style using this directive but instead to inline it in the HTML. This is useful for small scripts or styles that are only used on a single page or component and don’t need to be bundled with the rest of the scripts or styles.

However this means you will be opting out of Astro’s automatic script and style optimization and you will have to manage the optimization yourself. So Astro will not bundle, deduplicate or minify the script or style using this directive.

define:vars

Define Vars allos you to pass server side variables from your component into the script or style tag. This basically means that you can pass different vars from say your react or solid component into the <script> or <style> where they can be used for conditional styles or interactivity.

is:raw

This directive will tell Astro to treat the children of this element as raw Text. This is useful for when you wish to opt out of Astro templating syntax for whatever reason.

Can you deploy Astro to Vercel?

Yes, Vercel even has a astro build template for you to use. Astro can easily and seemlessly be deployed to Vercel.

Can you deploy Astro to Netlify?

Yes, Astro can be deployed to Netlify as well. Netlify has built in support for Astro and you can easily deploy your Astro project to Netlify.

Does Astro support Tailwind?

Yes Astro does support Tailwind, in fact it has built in support for Tailwind. You can either configure to use Tailwind when you create your project or add it in later by running npx astro add tailwindcss and then configuring it to your liking.

Does Astro support CSS Modules?

Yes Astro has built in support for CSS modules simply name your modules as [name].module.css and Astro will automatically treat them as CSS modules.

Does Astro support WASM?

Yes Astro supports WebAssembly using the browsers WebAssembly API, meaning you can load WASM files directly in your Astro project and use them as you would any other JavaScript file.

Does Astro support Bun?

It’s the other way around, but yes Bun and Astro work fantastically together and you can use Bun to build your Astro project.

Conclusion

As you can see Astro is an amazing tool that comes with a lot of DX niceties out of the box, it is production ready, has a great community and dev team behind it and is a great choice if you wanna build a website or webapp that is fast, accessible and SEO friendly and has most of it’s content pre-rendered via SSG or SSR. I’d highly recommend giving Astro a try for your next project.

Keep reading

If you liked that one here's another:
Three different states - Remote, App, and Local

Wanna show support?

If you find my sporadic thoughts and ramblings helpful.
You can buy me a coffee if you feel like it.
It's not necessary but it's always appreciated. The content will always stay free regardless.