This post is a folder. The Markdown lives in index.md and the components it uses — a little animated drivetrain, drawn as SVG — sit right beside it:
content/posts/how-do-bikes-work/
├── index.md
└── Drivetrain.vue
Co-located components are referenced by file name, exactly like the global ones in src/components, and they ship only with this post’s chunk.
Gears
A bicycle is two wheels and a lever. The crank turns the chainring, the chain turns the cog on the rear wheel, and the ratio between them decides how far each pedal stroke moves you. Shift up and watch the wheel speed up relative to the crank:
That’s an interactive SVG animated with requestAnimationFrame — it rendered its first frame on the server and started animating the moment it hydrated.
Heavier things
The same pattern carries further. WebGL scenes only exist in a browser, so they go inside ClientOnly with a placeholder for the server-rendered page — like this Three.js wheel, which loads the library on demand and orbits when you drag it:
Three.js is vendored once in the app archive and fetched by this scene at runtime — every other page on the site loads zero bytes of it.
Why folders
Some posts are mostly words. Those stay as a single .md file and ship zero JavaScript. When a post outgrows that — diagrams, widgets, scenes — it graduates to a folder and takes its components along for the ride.
