To use a UI framework, we need to add its integration, so we did
npx astro add react to add the react integration.
Then we will create an ordinary react component, just as we would in a react page, and import it and place it in a page. To mark that component as an island, we use a
client directive. The client load directive hydrates the component during the initial page load.
client directive has several different loading strategies you can use based on your usecase:
[0:53] We could still use those frameworks even without the islands, but as I mentioned, Astro would just render their output as static HTML so no interactivity would be available, even though we're talking about React or Vue components.
[1:06] To understand the Astro islands better, let's build a Like button component for our articles page. First, we need to add the UI framework integration. Astro comes with a built-in integration for React, which we can add by running npx astro add react. This will install all the necessary packages we need to run React and configure Astro to include React's runtime in our React components.
[1:31] Let's just proceed. If we check our Astro config file, we're going to see that there is the React integration added to our configuration object. Now let's create a new component in src/components and name it PostLike.tsx. This is a plain old React component.
[1:50] Let's export a default function called postLike that returns a button element. To make it look nice, I'm just going to add the following classes. To add the postLike component into our article page, all we need to do is just import it as a regular component, just like we're importing the layout component. Now we can place it below the content.
[2:16] If we leave it like this, Astro will run the React component during build time and save its output as HTML. This is not an island, at least not just yet. We need to tell Astro that this is an island component and that it needs to hydrate it.
[2:31] Hydrating components, or just hydration, is the process of taking pre-rendered static content and making it interactive on the client side. In our case, this involves loading React's runtime and using the actual static DOM to create its virtual DOM so that React can continue working from that point on.
[2:51] To tell Astro to hydrate our component and turn it into an island, we need to use a client directive on it. Client directives control how islands are hydrated on the page. If we want to immediately hydrate our like button, we're going to add the client:load directive. You can read this as hydrate this component on the client immediately on page load.
[3:15] Let's run the app now. Instead of just a button, Astro added the Astro island element that has attributes that define which is the component, which is the renderer, and how to hydrate it.
[3:47] Let's open the post-like component and add an onClick method to the button. We're going to show an alert, and it's going to say, "Hello, Island." Clicking the button now will show the Hello-Island alert as expected.
[4:14] One thing to note, and you might have noticed this, is that when we are in this component, we are in React land. You might have noticed that I used class name instead of just class. You might mix them at the beginning, but that's OK, you'll get used to them. Let's see different ways to hydrate our component.
[4:59] Let's change this to client-idle and hit refresh. Seemingly it's the same, but this time Astro will load the component after the page has loaded initially, which is better for performance. We use the idle directive on low-priority UI elements that don't need to be immediately interactive. Aside from the idle, we also have the visible directive.
[5:20] Let's demonstrate that. We can see that React and our component aren't loaded just yet, but when I scroll down in the article, just as it's about to become visible -- there we go -- these JS files gets loaded immediately.
[5:35] This has the lowest priority for hydration. It's good to be used on lower components that are further down the page, components that aren't visible above the fold. Imagine that this was a resource-intensive component. If the user doesn't scroll down to it, it will never load, and that's pretty good.
[5:54] There's a couple more directives. Media will load and hydrate the component only for certain CSS media queries, for example, mobile menu buttons, etc. There's only, which skips HTML server rendering and renders the component only on the client side.
[6:11] It acts like the load directive. It loads, renders, and hydrates the component immediately on page load. When using the only directive, you have to pass the correct framework as a value. Since Astro doesn't run the component during build time, it doesn't know what framework you're using in it, so you have to explicitly define it.
[6:58] To use a UI framework, we needed to add its integration, so we did npx astro add react to add the React integration. Then we created an ordinary React component, just as we would in a React page, and imported it and placed it in the page.
[7:14] To mark that component as an island, we use the client directive. The client:load directive hydrates the component during the initial page load. The client:idle component hydrates it after the page loads. The client:visible hydrates it only and if it gets visible. The client:media hydrates it only when the media query is met, and the client:only skips the server side pre-rendering and hydrates it only on the client side during the initial page load.
[7:45] Using these client directives in a smart way will make our website load faster and ship less files, which in return will improve the user experience of our website.