Widgets in posts

When a post needs something the reader can move, and how that gets wired in.

Most posts are prose. Occasionally a post needs something the reader can actually move, and a static diagram won’t do it. That’s what this file is for — it’s an .mdx post, and it hydrates a React component.

The rule

A post is .md until it needs to import a component. Then it becomes .mdx. That’s the entire decision.

This matters more than it sounds, because Astro’s client:* directives only work on components imported directly into an .mdx file. They do nothing in plain .md. So callouts and similar prose furniture can never be React — they have to be plain HTML from a remark plugin, which is exactly how Hello world renders its callouts.

An actual widget

1.000.750.500.250.00steps →
Drag to change the half-life.

That’s a React island. It ships its JavaScript only on this page, and only once it scrolls into view. Every .md post on this site still avoids hydrated framework islands and the React runtime; shared chrome uses only its small vanilla theme scripts.

Choosing a directive

  • client:visible — the default. Hydrates on scroll.
  • client:idle — for widgets above the fold.
  • client:load — only when it must be live immediately.

Anything heavier than it needs to be is just tax on the reader.