Astro Crash Course #12 - Client Islands (React)
Chapters10
Introduces the idea of islands and why Astro keeps most content static while enabling interactivity where needed.
Astro’s island architecture lets you hydrate only interactive parts with client islands using React, loading JS on demand.
Summary
Net Ninja explains Astro’s island architecture by contrasting static page rendering with selective interactivity. He demonstrates adding a React-based like button as a client island to a review page, showing how the page remains statically pre-built while interactivity is hydrated only where needed. The video walks through installing the React integration with Astro (npx astro add react) and enabling JSX support in tsconfig. A new component, likes.tsx, uses React's useState to track a local like count starting at three. Net Ninja shows how to import and render this component on the book details page, and emphasizes that Astro by default ships no JavaScript to the browser. To load interactivity, you add a client:visible (or client:load) directive to hydrate the component, with visible loading only when the component scrolls into view. He even demonstrates streaming in the JavaScript by scrolling to the bottom, where the component hydrates and the like button becomes interactive. Ultimately, the focus is on keeping most of the site static and sprinkling interactivity only where necessary, using teams’ preferred client frameworks. This approach balances performance with a snappy, interactive experience. Net Ninja notes that real implementations would fetch like counts from databases, but the example keeps data local for clarity and learning.
Key Takeaways
- Astro ships static HTML by default, ensuring fast page loads and minimal JavaScript delivery.
- Install the React integration with npx astro add react and enable JSX support in tsconfig during setup.
- Create a client island component (likes.tsx) using React's useState to manage local UI state (initial likes = 3).
- Import and render the likes component on the book details page to turn it into a client island.
- Use the client:visible directive to hydrate the component only when it becomes visible on screen, optimizing performance.
- Hovering or scrolling to the bottom of the page triggers the loaded JavaScript for the interactive island, demonstrating on-demand hydration.
- In real apps, the like count would come from a database, but the example focuses on the island hydration workflow.
Who Is This For?
This is essential viewing for developers using Astro who want to add interactivity without sacrificing performance. It’s especially useful for those exploring client islands with React or other supported frameworks.
Notable Quotes
"Okay then my friends. So far when we've been using Astro I've said several times that after the site gets built and deployed no JavaScript gets sent to the browser by default."
—Setting the baseline behavior of Astro regarding JavaScript delivery.
"The idea is to keep as much of the site or page as possible static content and then only add the islands where we absolutely need that interactivity."
—Central principle of island architecture.
"By default, Astro doesn't ship any JavaScript to the browser. It strips it all out of the components."
—Explains why client islands are necessary.
"We can use the load option, which tells Astro to load the JavaScript for this component and hydrate it immediately when the page reaches the browser."
—Describes hydration strategies.
"Or what I prefer using is the visible option which tells Astro only to load the JavaScript in the browser and hydrate the component when this component is visible on the page."
—Guidance on practical hydration timing.
Questions This Video Answers
- How do client islands in Astro differ from traditional client-side rendering?
- What is the difference between client:load and client:visible in Astro?
- How do you add React to an Astro project using the official integration?
- Can Astro islands fetch data from a database, or do they only work with local state?
- What are best practices for hydrating interactive components to optimize performance?
AstroAstro IslandsClient IslandsReact integrationHydration strategyclient:visiblenpx astro add reactJSX in TSConfig
Full Transcript
Okay then my friends. So far when we've been using Astro I've said several times that after the site gets built and deployed no JavaScript gets sent to the browser by default. And so naturally Astro sites are generally fast and performant. However, sometimes you need some interactivity in the browser. For example, clicking a like button on a post which then updates in real time in the browser how many likes that post has. So in cases like this, you'll need some JavaScript to add that interactivity in the browser. Now to accommodate this, Astro utilizes something called island architecture where we can essentially add islands, client islands of interactivity to an otherwise static page.
So if you take a look at this diagram of a web page, you can see we've got several sections on there that are static, right? Like a sidebar at the main content and the footer. And it also includes a couple of interactive sections that might require JavaScript in the browser. So this page would be pre-built and rendered by Astro at build time as normal to include all these different static sections and unless we state otherwise the island sections as well. Then when the page reaches the browser those islands can be hydrated and sent the JavaScript needed for them to work.
So the idea is to keep as much of the site or page as possible static content and then only add the islands where we absolutely need that interactivity. And these islands can be built and added to your project using libraries like React or Huosfelt which specialize in that browser interactivity. So then let's head back to the code and try a little example. So then what I'm going to do is add a little like button to the review page so that a user can click it and then that's going to update some local state in the component to update how many likes the review has.
And we'll be using React to make this component. Now in reality this component might reach out for a database like Firebase or Superbase or it could just hit your own endpoint to run some logic on the server. Uh but for the sake of learning about client islands and how to make them, we're just going to use some dummy data instead. So then how do we make a client island? Well, first of all, we need to install the library we want to use for the island, which is in this case React and then integrate it with Astro.
Now, the easiest way to do that is by using an Astro integration maintained by Astro. And there's integrations for several different libraries including uh React, Smeelt, Vue, Solid, Alpine, etc. So, we can install the React integration by coming to the terminal and you can see I've already stopped the dev server. So, I can install this and then we type npx astro add followed by the integration name which is react. Then we can hit enter. Next, it's going to ask us if we want to install these packages, which we do. So, we can hit enter to select yes on that.
Then, it's going to ask us if we want Astro to update the config file to register this new integration, which we do. So, I'm going to hit enter again. And then, finally, Astro wants to add some compiler options to the TS config file so that we can use JSX. So, we'll hit enter once more to select yes for that as well. And now just like magic, we can use React in the project. So then let's make a new React component. And it can go in the same place as the other components. They don't have to have a separate folder.
I'm going to create a new file inside the components folder right here. And I'm going to call this likes and then.tsx. And this is not going to be a tutorial about React. If you want to learn about React, I've got plenty of tutorials all about that on my YouTube channel or netinja.dev. Instead, what I'm going to do is just paste in this React component. I will quickly go through it. First of all, we're importing use state from React. That's a hook that we can use to manage some local state in the components. So the component name is right here.
This function called likes. Then we have this state called likes. And then we have a function to update the state called set likes. And the initial value is three. I've just plucked that from thin air. It could be whatever you want. It doesn't really matter. Then down here we return the template for this component. So it's a div with a class name of likes. And then we have a paragraph tag right here that outputs the likes in curly braces. So that's going to be three to begin with, right? And it says that many people like this review.
Then we have a button that says we want to like this. And when we click on this button, it's going to fire this handleclick function. Inside here, we run this set likes function to update the like state. We take the previous value and we add one to that each time. So it's going to go to four, then five, and so forth. So I also want to just add a little bit of styling for this as well. And I'm going to do that inside the global styles within the layout right here. So let me come down to the global style tag which is this one.
And at the bottom I'll paste in just a little bit of styling. So we grab that class likes. So we give it a border top etc. Then we style the button inside that as well. All very simple. Okay. Okay, so now we've got the React component made and we want to use in the application on the book details page. So let's open that page up. And the first thing we need to do is import the like component at the top of the front matter and we can do that by saying import likes and that comes from two folders up.
So do slash then another do forward slash then into the components folder and then we want the likes file. After that we can use it in the template. So let's come to below the content component and we're just going to add it in right here. Now then if we save this and preview then we will see the templates of this lights component in the browser and that's because Astro still pre-builds the React component and adds it to the page by default but it also strips out all of the JavaScript by default as well. And if we scroll right down this page we should eventually be able to see the component which has already been rendered.
But when we click on the button, nothing happens because again, by default, Astro doesn't ship any JavaScript to the browser. It strips it all out of the components. So the way we can tell Astro to send the JavaScript is by adding an attribute to the component where we use it, which is client followed by a colon. And then we've got a couple of options. We can use the load option, which tells Astro to load the JavaScript for this component and hydrate it immediately when the page reaches the browser. Or what I prefer using is the visible option which tells Astro only to load the JavaScript in the browser and hydrate the component when this component is visible on the page because it's sitting right at the bottom of the page content.
So it makes sense to only load it when a user scrolls all the way down and they can see it. Right? So I'm going to save this now. Then we'll try it out. Okay then. So, I've already refreshed the page and I've cleared the network tab to show you how the JavaScript only gets loaded when we scroll down enough to see the components. So, if we keep on scrolling, eventually we're going to be able to see it and all the files and JavaScript needed for the component get loaded in. And now, if we press the like button, we should see that everything is working.
Awesome. Okay. So, in reality, rather than hard coding the React state, you'd probably be getting those numbers from a database or something. And that's fine. nothing changes except for your logic in the React component to do that and we'd still load it into the page the same way. So hopefully you've got an idea now about how client islands work in Astro. I think they're a really cool idea and they let us sprinkle in that interactivity only when we really need it using whatever framework that you prefer.
More from Net Ninja
Get daily recaps from
Net Ninja
AI-powered summaries delivered to your inbox. Save hours every week while staying fully informed.









