How interactive posts work on this site
metareact

Most of this site is plain HTML. The blog index, the comic pages, the page you’re reading right now — none of them ship a JavaScript framework. But sometimes a post wants to show you something instead of telling you, and for that there’s a pattern I call a code canvas: a small React component embedded directly in the post.
Here’s one now. Drag the sliders, click inside the box:
The pattern
Posts on this site are MDX, which means they’re
Markdown that can import React components. The particle toy above is a
single component that lives in src/components/canvases/, and the post
embeds it with two lines:
import ParticlePlayground from '../../components/canvases/ParticlePlayground.tsx';
<ParticlePlayground client:visible />
The interesting part is client:visible. This is an Astro hydration
directive: the component is
rendered to nothing at build time, and its JavaScript only loads when it
scrolls into view. If you never scroll down to the toy, you never download
it. Everything around it stays static.
Rules I follow for canvases
- One component, one folder. Each canvas is self-contained in
src/components/canvases/. No shared state, no global stores. client:visible, notclient:load. Readers get the prose immediately; the toy can hydrate whenever it gets there.- Respect
prefers-reduced-motion. The particle toy starts paused if your OS asks for reduced motion — there’s a Play button if you want it anyway. - Degrade politely. With JavaScript off you see an empty frame and a caption, not a broken page.
That’s the whole trick. The site stays a pile of fast static pages, and any post can opt into exactly as much interactivity as it needs — a slider, a simulation, or a whole game.
Slugmail
New games, strips, and posts in your inbox. No spam, only slime.
Enjoyed this post? Buy me a coffee