Use React/Svelte/Vue in the same application and ship 0kb JavaScript by default! 🪐
Tags: javascript, webdev, react, astro
Published: 2022-02-23 16:12:13

## **Astro.js** 🪐
A static site builder for the modern web!
To follow along you can clone this [repo](https://github.com/joetifa2003/astro-test) or check it out now on Codesandbox [here](https://codesandbox.io/s/astro-react-vue-svelte-counter-app-r39flb?file=/sandbox.config.json)

## Why do we need yet another JavaScript framework?
Astro.js is a static site builder with some unique features like:
- You can use any frontend framework or even multiple frameworks
- Ships with 0 JavaScript by default
- Multiple ways to load JavaScript for interactivity _(ex. when the component is visible)_

<figure>
  <img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ttysqe02hlbireq3bpsh.gif">
  <figcaption>Preview of astro.js using multiple frameworks!</figcaption>
</figure>

## Let us start building the app
![The app preview](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5b47n39p55vgtw3ujzyk.png)
We have 3 important folders:
- Components for the different JavaScript components
- Pages for Astro pages which combines the components
- Styles for some basic CSS styles

### Now we implement each component:
- React component
![React component implementation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e12f0w91ke92518dal6y.png)
- Vue component
![Vue component implementation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oge0ywt0h4ml48lmbtt3.png)
- Svelte component
![Svelte component implementation](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xt29cznigfjy4xmudq3t.png)

### And here is the fun part, The actual Astro page 🪐
![Astro.js index](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zdhiv11mv9ta8vmx9wb7.png)
As you can see between the "---" we can import all of our components and CSS, Any code here will run only on the server and will not be sent to the client.

So we imported all of our components and placed them inside the HTML, Now we are all set! Let us see what happened.

<figure>
  <img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1tuybem7d9pq277shnz1.gif">
  <figcaption>Oops, it's not interactive</figcaption>
</figure>

Astro rendered all the components correctly but they are not interactive, Why?

## Astro hydration strategies!
Astro ships zero JavaScript by default thus making the components static. If we want to make components interactive we must "Hydrate" them, Which basically means loading the necessary JavaScript to make it interactive.

We have multiple ways to do this:
- Hydrate the component on page load (client:load)
- Hydrate the component when visible (cllient:visible)
- Hydrate the component when matched to a specific media query (client:media={QUERY})
You can pass these as props to the actual components.

We will use client:visible for this simple example
<figure>
  <img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nmzg6yqzi1y9j1ksr8jq.png">
  <figcaption>We pass client:visible to all components</figcaption>
</figure>

<figure>
  <img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xymzlu5m601wlk1gmbml.gif">
  <figcaption>Yes! now we have 3 different components from 3 different frameworks all on the same page and interactive 🪐💙</figcaption>
</figure>

As you can see we now have 3 different components with different frameworks all on the same page! How cool is that!

## Benefits of Astro 🪐
- Multiple frameworks
- 100% Static HTML, No JS
- On-Demand Components: Need some JS? Astro can automatically hydrate interactive components when they become visible on the page.

A perfect use case for Astro is a mostly astatic website like a blog that has little interactivity and the need for performance.

# Thank you for reading 🪐💙
Thank you everyone for reading this 💙
If you like this content consider following me on Twitter for more 💙

Happy coding!

Twitter: https://twitter.com/joetifa_dev
Website: http://youssefahmed.vercel.app/
GitHub: https://github.com/joetifa2003