Why This Portfolio’s Content Lives With the Code

By Daniel Ensminger

Week of published 4 min read

Moving the portfolio’s editorial content out of a hosted CMS made publishing less magical, but it also made every public claim reviewable, versioned, and easier to keep in sync with the product.

In April I removed the portfolio’s BaseHub dependency and moved its long-lived content into the repository.

That was not a verdict on hosted content systems. A CMS is the right tool when editors need to publish independently, when content changes much more often than code, or when a structured editorial workflow matters more than a Git history. This site had a different shape: one author, a small number of carefully edited pages, and public claims that often change alongside the implementation.

For that shape, a second source of truth was creating more work than it removed.

The important split is not CMS versus Markdown

The useful question was: which data should travel with a deployment, and which data needs to change while the application is running?

The portfolio now keeps the first category in the repository:

  • biography and site copy in typed TypeScript data;
  • long-form Work entries in Markdown;
  • blog posts in MDX with validated frontmatter;
  • registered-IP material in its own content collection;
  • public route descriptions and machine-readable documentation beside the code that renders them.

The second category still belongs in services designed for live state. Comments and reactions can change without a deployment. Reading and activity snapshots come from integrations. The contact form sends a message rather than editing a file.

That boundary is more useful than insisting that every byte live in one place. Editorial truth is versioned with the site; visitor and integration state stays dynamic.

A file can still have a contract

“It is just Markdown” becomes a liability when any filename or frontmatter shape is accepted and failures only appear during a production build.

The blog loader therefore validates fields such as title, slug, description, issue date, publication date, tags, and visibility. Work entries have a separate shape. A file under content/work becomes a Work route; a published file under content/blog enters the blog archive, sitemap, command menu, and the portfolio assistant’s directory.

The important part is not the parser. It is that one content decision propagates through the public surfaces instead of being copied into five registries by hand.

This also makes omission deliberate. A draft can stay on disk with published: false while the public loader excludes it everywhere. That is much safer than relying on a hidden link or remembering not to add it to the sitemap.

Git is a useful editorial record

Portfolio copy contains claims about projects, roles, releases, and technology. Those claims deserve the same review discipline as code.

Keeping the source in Git gives every change a diff. A rewritten description can be compared with the previous wording. A removed project leaves a history. A date correction is visible. The build can reject malformed frontmatter before a deploy reaches production.

It also makes broad corrections practical. If a legal term, product name, or domain changes, the repository can be searched as a whole. The result can be checked across visible pages, structured data, the sitemap, and llms.txt instead of trusting a collection of unrelated editor screens.

None of that makes the content automatically true. Git preserves mistakes just as faithfully as good edits. It does, however, make the evidence trail and the review surface much clearer.

The admin can still be the writing interface

Repository-backed content does not require writing raw frontmatter forever. The x70 Admin can research a topic, prepare an MDX draft, show the sources and preview, and then publish the resulting file through the repository workflow.

That is the architecture I prefer here: the Admin is an authoring and review tool, while the repository remains the canonical publication record. If the Admin disappears, the articles are ordinary files. If the site is rebuilt, the same commit produces the same editorial archive.

The move made publishing a little less abstract. A post is a file, a review, a commit, a build, and a deployed route. For a personal portfolio, that explicit chain is a feature.

You can see the result in the current Work archive, blog, and Stack: different content types, one inspectable publication model.

👍
❤️
🔥
👏
🤯

Get infrequent updates on new projects.

By subscribing you consent to email updates. You can unsubscribe anytime. See our Privacy Policy.