Drop a React Component Into an Astro Page
React in Astro
After `npx astro add react`, you can write React components in `.tsx` and use them as Astro components with a `client:*` directive.
What you'll learn
- Author a React component
- Use it inside an Astro page
- Hydrate it with a client directive
A React component in an Astro project is just a .tsx file. Use
it in .astro files like any other component.
A React Component
// src/components/Counter.tsx
import { useState } from "react";
interface Props {
initial?: number;
}
export default function Counter({ initial = 0 }: Props) {
const [count, setCount] = useState(initial);
return (
<button onClick={() => setCount(c => c + 1)}>
Count: {count}
</button>
);
} Use It In An Astro Page
---
import Counter from "../components/Counter.tsx";
---
<h1>Counter Demo</h1>
<Counter client:load initial={5} /> Without client:*, the component renders as static HTML — the
button shows but doesn’t react to clicks. The client:load
directive ships the React code and hydrates.
Server-Render-Friendly Components
Most React components work out of the box. The exceptions:
- Components that access
window/documentduring render - Components that fetch in a
useEffectand break without one - Anything that genuinely cannot run in Node
For those, use client:only="react".
Sharing Components Between Astro Sites and React Apps
A .tsx component dropped into Astro is the same component you’d
use in a React app. You can move it between projects without
changes (assuming the component doesn’t import Astro-specific
things, which it shouldn’t).
What Hydration Looks Like in DevTools
Network tab: a small JS file loads when the directive condition
fires (immediately for client:load, on idle for client:idle,
etc.). Elements tab: the component’s DOM updates to the
post-hydration state.
Up Next
What you can — and can’t — pass as props to an island.
Passing Props →