New Domain, Who Dis?
October 19, 2025
A new place to call home
Just in time for the year's end, I finished a full revamp of my website. It's now powered by Next.js and features a blog and photo gallery. I also migrated to a new, slick, 3-letter domain which matches my GitHub handle and my initials.
Settling on a new design
When I was creating this website, I fell victim to a not-so-good practice of mine called design-while-you-code where I just rawdogged the design of the website as I developed it. There was a lot of going back and forth on the site's aesthetic, and I couldn't decide whether to go for a minimal, tech-y, or quirky design. I also wanted to sprinkle in lots of micro-interactions and animations, especially on the landing page, and fell down a rabbit hole of experimental components and designs. The subtle stuff like hover effects and ambient loops seemed interesting, but it quickly became obvious they were in the wrong direction. They were cool, but they were too distracting from the content.
Seeking inspiration from other popular portfolios like Lee Robinson's and Hayden Bleasel's, I opted for a minimal, lightweight vibe for my website. This meant scrapping most animations and keeping the JavaScript to a minimum.
The result is a design that focuses on the essentials. The palette is mostly grayscale with a few accents, just enough to color to add personality without pulling attention away from the page. I think I pulled it off decently.
Showcasing my photography
Over the past three years, I've been getting into photography and I've wanted a home for my pictures outside of Instagram. Now I finally have it. Posting on this website feels more personal, and I get full control over how images are processed and displayed.
My first pass at building the gallery was a basic page that imported images from public/, but it quickly ran into problems:
- Slow page loads due to large, high‑quality images.
- Jarring empty boxes while images streamed in.
- The same original image was used for both small thumbnails and the lightbox, so you'd download big assets even if you never needed them
The approach: Cloudflare Images + an upload pipeline
To fix these issues, I moved storage and delivery to Cloudflare Images. It’s cheap, has free unlimited egress, and supports on‑the‑fly transforms. I wrote a small upload script to automate everything end‑to‑end:
- Reads all files in
assets/photos/and supports common formats. - Computes dimensions and generates a blurred low-quality image placeholder (LQIP) with plaiceholder for the "blur‑up" effect.
- Uses the filename as a stable Cloudflare image ID.
- Tracks uploads by filename and last modified time in
src/data/upload-tracking.json, so only new or changed files are uploaded. Modified files replace the old version. - After upload, builds a base
imagedelivery.net/<accountHash>/<imageId>URL and writes a compact manifest tosrc/data/photos-metadata.jsonwith the image id, base URL, width/height, and the LQIP.
Now I just add files to assets/photos/, run the script, redeploy, and the gallery picks them up during build time.
Rendering: fast thumbnails, no layout shift, and smooth blur‑up
On the page, the gallery reads the generated manifest and renders a masonry layout. A few key optimizations make it feel snappy:
- Tiles start with a small blurred placeholder, then fade into the real image without any empty boxes.
- The grid reserves space using each image's aspect ratio, preventing layout shifts.
- Images are rendered with Next.js
<Image>and a custom loader that turns the base Cloudflare URL into a flexible variant like/width={w},quality={q}. Next creates multiple sizes, and withsizesandsrcsetthe browser uses what it needs. - Thumbnails are requested at 75% quality for a good size to clarity balance.
Lightbox: full quality, only when requested
Thumbnails are stay lightweight. When you open a photo, the lightbox fetches a high-quality version on demand using the same base URL with quality=95, so you get the best version only when you actually view it.
Result
The result is a gallery that feels instant: thumbnails fade in smoothly with no layout shift, and full-quality files are fetched only on demand in the lightbox. As the viewport or device pixel ratio changes, the browser pulls an appropriately sized variant, keeping images crisp while minimizing data. The pipeline is also efficient, only requiring me to add photos to a folder, run the uploader, and redeploy.