Skip to content

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:

Click anywhere in the box to fling a burst of particles.

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

  1. One component, one folder. Each canvas is self-contained in src/components/canvases/. No shared state, no global stores.
  2. client:visible, not client:load. Readers get the prose immediately; the toy can hydrate whenever it gets there.
  3. 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.
  4. 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