Posts about webdev
26 posts
-
GRD 040
#74A
Stati 2 started as four bug reports
I filed four bug reports about Stati's templates in one afternoon, each with a fix. Two hours later I threw the fixes away and broke the template API instead.
-
GRD 039
#319
@stati/images: responsive images and link preview cards for Stati
AVIF and WebP at several widths, and an Open Graph card for every page drawn without a browser. It ships as a separate package, and I had my reasons.
-
GRD 038
#238
The dev server got slower with every save
Windows eating file writes, a watcher that watched too much, and the instruments I built into Stati so the next slowdown shows up on a pull request instead of in my hands.
-
GRD 037
#6B1
What Stati is, and what it isn't
Where a small, TypeScript-first static site generator fits next to Astro, Eleventy and Hugo, and when you should pick one of those instead.
-
GRD 036
#A42
Why I'm building Stati
I rebuilt this blog on a new framework every few years and the blog never changed. So I wrote a static site generator I intend to keep for ten years.
-
GRD 035
#9B1
Goodbye Serverless: Deploying a Puppeteer Lambda via Bitbucket OIDC
I rebuilt my OG-image generator as a container Lambda and ship it from Bitbucket Pipelines over OIDC: no long-lived AWS keys, images land in S3, and I expose it via a Function URL.
-
GRD 034
#149
React callback refs: what, why, and why not
Callback refs are a small React feature that solve real problems when object refs fall short. Here's how they work, when they shine, and when to avoid them.
-
GRD 033
#693
Running TypeScript in Node without a build step
Node 23 strips types out of the box and TypeScript 5.8 has a flag that keeps your code strippable. For scripts and small services I dropped tsx, though the compiler still has a job.
-
GRD 030
#741
Type predicates, and the ones TypeScript 5.5 now writes for you
filter(Boolean) never narrowed, so every codebase grew a pile of is functions. TypeScript 5.5 infers the simple ones, though not all of them, and a hand-written one can still lie to you.
-
GRD 029
#B27
The TypeScript utility types I use
A hand-rolled mapped type in a code review sent me back to the handbook, because most of what we need already ships with TypeScript. These are the ones I use, plus a trap in Omit and the new NoInfer from 5.4.
-
GRD 027
#62B
When I reach for React's memo, useMemo and useCallback
A lot of the memoisation in a React codebase does nothing, and some of it costs more than it saves. These are the few cases where I still use it.
-
GRD 025
#945
The tsconfig module settings I finally understand
module, moduleResolution and the new verbatimModuleSyntax were three knobs I turned until the errors went away. TypeScript 5.0 finally made me read what they do, and now I know why my Vite app and my Node service need different ones.
-
GRD 023
#A15
How I type React components in TypeScript
After a few years of typing React components I'm down to a handful of shapes, and I let the compiler infer the rest. React.FC isn't one of them anymore.
-
GRD 022
#631
TypeScript trusts your API too much, so I added Zod
A backend rename turned a typed field into undefined and the compiler never blinked, because types are gone at runtime. So now the data gets checked where it comes in.
-
GRD 021
#842
Fixing a laggy search filter with useDeferredValue
Typing into the filter above a long table felt like typing over a bad SSH connection. React 18 has a hook for exactly this and the fix was one line. Well, two.
-
GRD 020
#42A
Why I stopped writing enums in TypeScript
Enums were the first thing I reached for when I started with TypeScript. Then I read what they compile to. A const object does the same job with less magic, and TypeScript 4.9 just added the piece that was missing.
-
GRD 018
#3A7
Moving my tests from Jest to Vitest
Eight months ago I left the tests behind when I moved to Vite. Moving them took an evening. Reading them took longer, because most of them tested the wrong thing.
-
GRD 016
#259
Why React 18 runs your effects twice
We upgraded to React 18 and every request in the dev tools showed up twice. React does that on purpose, as a test, and our effects were failing it.
-
GRD 015
#13B
Discriminated unions: the TypeScript feature I'd teach first
Three booleans for one request gave us a spinner on top of an error message. One union with a status field fixed it, and now the compiler tells me when I forget a case.
-
GRD 013
#14B
Moving a Create React App project to Vite
Create React App 5 landed this week after a year of waiting, and I still moved my side project to Vite. It took an evening, mostly spent renaming things.
-
GRD 008
#543
Purge Cloudflare cache after deploy on Netlify
Let's double up on the CDN and purge the Cloudflare cache when we deploy.
-
GRD 007
#4B9
How to solve missing chunk code splitting errors after deploy
Code splitting is a great way to avoid huge javascript files, but weird things can happen after a deploy. Let's fix that.
-
GRD 004
#243
Creating modular HMVC applications with CodeIgniter 4
Here is how I like to create modular HMVC applications with the newest version of the CodeIgniter framework.
-
GRD 003
#964
Rage against the popup
I grew up in a time when popups were bad. Everyone hated them, so they invented popup blockers. Then it all went away. Almost.
-
GRD 002
#1B6
Generating Open Graph images to S3 on AWS Lambda
This is how I generate my Open Graph images in the cloud at build time.
-
GRD 001
#356
How I designed and coded my static blog
Let's see my creation process for this blog and the chosen technology behind it.