I recently tried to use Preact with Astro. Since I found no decent tutorial on how to use those two together, I decided to write one.
If you don't know Astro, you should definitely check it out. Astro is a new modern static site builder that allows us to use React/Preact, Svelte and Vue components all together, while shipping only the absolute necessary client-side JavaScript, using a technique called "Partial Hydration". That results in really fast sites with less JavaScript. They just released v0.21.0, which introduced a new, faster compiler written in Go a new build engine powered by Vite.
Preact is a "Fast 3kB alternative to React with the same modern API". It's smaller than React but shares most of it's features (Hooks, Context), so you can write normal React code but benefit from better performance.
So how can I use Preact components with Astro?
The fastest way to do this, is to select Preact as your framework in the Astro CLI when you setup a new project. This tutorial presupposes that you want to add Preact to an existing Astro project.
First you need to install a renderer for Preact, and the Preact library itself.
npm install --save-dev @astrojs/renderer-preact preact
Then you need to add the just installed renderer to the Astro config file, astro.config.mjs. When you open it, the renderers
property should be an empty Array. Add the @astrojs/renderer-preact
package to the Array.
renderers: ['@astrojs/renderer-preact']
That's all you need to setup Preact with Astro! ๐
Now you can write your Preact components as .jsx or .tsx files and import them to your Astro pages.
For example, this is how you would write a simple Counter component in TypeScript (.tsx):
// /src/components/Counter.tsx
import { useState } from 'preact/hooks'
export default function Counter() {
const [count, setCount] = useState(0)
return (
<div className='counter'>
<button onClick={() => setCount(count - 1)} disabled={count === 0}>
-
</button>
<h2>{count}</h2>
<button onClick={() => setCount(count + 1)}>+</button>
</div>
)
}
You can import the component like this:
---
// /src/pages/index.astro
import Counter from '../components/Counter.tsx'
---
<Counter client:load />
Tip: The client:load
snippet you see above comes from Astro's Partial Hydration. If we leave this away, Astro would only render the components markup, without any interactivity, to ship less client-side JavaScript. You can learn more about Partial Hydration in the official Astro Docs
Happy hacking!
Top comments (0)