Tilbage til indlæg
2. maj 20263 min læsetid

Releasing my portfolio

A small write-up on finally putting this portfolio online, how I structured it, and why I kept the content system lighter than a CMS.

Editorial cover for Releasing my portfolio.
Indholdet i indlæggene er i øjeblikket kun tilgængeligt på engelsk.

I finally shipped this portfolio instead of leaving it in the usual half-finished state where the structure exists, the ideas are there, but nothing is actually live. The goal was simple: make something that feels personal, structured, and easy to keep updating without turning it into a second product to maintain.

The stack

The site is built with Next.js 16, React 19, TypeScript, Tailwind CSS 4, and next-intl. I wanted a setup that stays fast to edit and easy to reason about, so I avoided building a heavy content pipeline. Most of the content lives in typed files under src/lib, which makes the whole thing feel closer to a real codebase than a blog engine bolted onto a portfolio.

The content model

Instead of one long page trying to do everything, I split the site into collections: projects, gear, tools, and posts. They all share the same overall structure, but the card layouts are tuned to the kind of thing they are showing. Projects are richer and closer to case studies, gear stays practical, tools are lightweight, and posts are more reading-oriented.

A lot of the work was not really about adding more content, but about making the structure hold up once real content started going in. That meant cleaning up the layouts, making the collection data typed, and keeping the component system predictable enough that new items could be added without random CSS hacks or one-off exceptions everywhere.

Localization

Localization ended up being more selective than global. The interface itself is translated, and the shorter browsing content like projects, gear, and tools now follows the active locale. Posts are different. I do not want to maintain fully translated article content right now, so the posts stay in English and the site simply says that clearly when another locale is active.

The practical details

I also had to fix some structural issues along the way. One of them was the layout split itself: global concerns like theme initialization belong in the root layout, while locale-specific UI belongs in the locale layout. Another was making sure the collections actually resolve localized data cleanly instead of only translating the surrounding labels.

The less visible parts matter just as much: localized routes, generated search indexes, archive pagination, metadata, sitemap and robots output, content validation, route tests, component tests, smoke tests, typechecking, Biome, and CI. Those pieces make it easier to keep adding work without guessing whether the site still holds together.

Visually, I tried to keep the site consistent without making every section feel identical. Some of the artwork is custom SVG-based illustration, some of it is more representational, and some sections are intentionally simpler. The important part is that the system stays understandable. If I want to swap assets, rewrite a project, or add a tool later, it should be obvious where that change belongs.

Why it stays small

That is probably the main point of this portfolio. It is not meant to be a perfect polished artifact that never changes. It is meant to be a place where my work, setup, tools, and writing can live in one coherent system that is small enough to keep evolving. Releasing it matters more than endlessly redesigning it in private.