Blog · page 14
Notes on engineering, design, and everything in between.
The @/ alias lives in three configs, and all three are required
Deep relative imports are banned project-wide, and the price is configuring the alias in three places. Miss one and you get editor errors, a broken build, or silently dropped styles.
zod as a frontmatter contract: bad articles fail the build
The Content Collections schema is the single source of truth. A title over 120 characters, a mangled date or a string where an array belongs fails immediately instead of silently dropping a page.
Why I built yet another personal site
Not because there was nowhere to write, but because there was nowhere to put writing, small games and tools side by side.
A zero-config registry: adding a game means adding a directory
App lists, detail routes, the home page picks and the sitemap are all discovered by import.meta.glob. The price is Vite's hard rule: literal relative paths only.
No client:only for app pages: a static shell plus an explicit mount
Game and tool pages are a shell plus createApp, not client:only. I own the loading, ready and error states, and the retry button actually works.
Views hold no logic: all data assembly lives in src/server
A page here exports a route, imports two components and passes props. Everything else — fetching, paths, dates — happens in src/server. Here is what that buys, and the type constraint it forces.
