Cleaning Up 14 Copies of the Same Code
Pulled duplicated fetch helpers out of 14 portal pages into one shared script, deleting 204 lines in the process.
Tag
44 posts in my garden · read my essays
Pulled duplicated fetch helpers out of 14 portal pages into one shared script, deleting 204 lines in the process.
Redesigned the /technical page with a repo dashboard and gave the home page variable-density sections — four changes in one session.
Small housekeeping update: corrected the blog's section count and documented the daily log format in the pipeline's memory files.
Added a full DNA ancestry section to the ocampo.io family page and fixed a migration map that looked like abstract art.
Test posts to check the blog layout, plus a rewrite of how daily logs get made.
A quick walkthrough of how to expose a local service to the internet using Cloudflare Tunnel, without opening any ports.
Seven changes today: the blog gets hand-drawn icons and a personal voice, plus ocampo.io launches as a family landing page.
Updated the blog's content model to match the vault — five sections, new fields for time and location, technical card variant, and the garden as an umbrella concept.
Added a feature doc for an ambient music player idea — no timeline, just capturing the vision so it doesn't get lost.
Merged two home pages into one, dropped three languages, then migrated ten pages to a brand-new frontend.
Built the system that watches my notes folder and auto-publishes coding updates as blog posts — and it wrote its own announcement.
One-line fix: macOS calls file moves 'Renamed', not 'Created', so the watcher was missing everything I dragged into Published/.
Added two ongoing pages about writing voice and process, plus fixed the watcher to notice edits — not just new files.
Added full-text search to the blog — press Cmd+K and start typing to find anything across all posts.
The right-side table of contents on longer posts now highlights which section you're reading as you scroll.
Added a three-state dark mode toggle, plus proper error and 404 pages for when things go sideways.
My post template was rendering as a live article on the blog — fixed the filtering and cleaned out some leftover files.
Fixed HTML structure warnings on post cards and a mobile layout issue where the search box wasn't centering right.
A quirk in how Next.js handles URL objects was crashing every page locally during development. Eight lines changed, very annoying bug.
A big visual pass on the blog — portrait hero, card variants, leaf dividers, collapsible tag filter, and newsletter CTA with RSS fallback.
Six changes in one morning: the compliance portal got a data layer, a real interface, auto-synced types, two bug fixes, and a dev shortcut.
Documented the exact X/Twitter developer setup for Postiz — including the OAuth gotchas, callback URL tricks, and a shared rate limit warning.
Removed a leftover library from the blog project after the feature it powered was deleted months ago.
Added RSS feeds for every section, a machine-readable posts index for AI tools, richer search metadata, and restyled link preview images.
Added a /tags page listing every topic on the blog, sorted by how many posts use each one.
Added a newsletter signup form (powered by Beehiiv) to the home page, post footer, and site footer — plus a whole new site footer.
Updated the website's architecture doc to reflect four slices of recent work — RSS, feeds, tags, and the newsletter footer.
Added a small guard that blocks accidental direct saves to the main branch on the blog project.

A senior-designer review of the current site, four aesthetic dialects compared, and the hybrid I picked to hold software, garden, family, and photos in one home.
Swapped three different pitches for three different audiences with one real story: a Miami Beach condo, 940 documents, $6.04.
Tags existed in every blog post since day one — I just never wired them up to actually appear on the page.
Migrated honest-cam's state to SQLite and self-hosted the portal on a Mac mini via Cloudflare Tunnel.
Four byte-identical duplicates left over from a rsync destination mistake, and the one-line Contentlayer slug regex that caused it.
Developer QoL upgrades plus Spanish, Portuguese, and Italian landing pages via an AI translation CLI.
Wired up Web Vitals, redesigned the landing pages, rewrote all the copy, and documented the process.
A statutorily compliant association website with 940 auto-sorted docs, PDF attachments on Xero transactions, and four landing pages.
Architecture docs, an AI-powered OCR pipeline, Xero sync, owner portal, study quiz fixes, and a mobile study app — all in one sitting.
Starting the honest-cam project with a Python + TypeScript monorepo, a YAML-driven document reorganization engine, and SHA-256 idempotency on a 958-file real-world dataset.
Retiring the Twitter CTA in favor of a Substack email list, adding a 'meet my family' link to ocampo.io, and replacing the sidebar logo with a new SVG pointing to the personal site.
The inevitable follow-up to adding GTM: the browser's CSP was blocking the script, so this PR adds googletagmanager.com to script-src and img-src in next.config.js.
The one-character follow-up to PR #4: removing the stray colons from the CSP directive names so the browser stops ignoring the whole header.
First instrumentation on the blog: a gtag wrapper in lib/ga.js, a custom pages/_document.js with the Global Site Tag, and no npm dependency.
The shortest possible PR: collapsing a two-line JSX attribute into one. Shipping it anyway, because PRs are free and branch hygiene matters.
Universal Analytics is on the way out, so this PR migrates to GA4 via Google Tag Manager loaded through next/script, and renames everything from stevieismagic.com to steven.ocampo.io.