Notes on enginering leadership and software development.

Obsidian, Next.js, and Vercel


Contentlayer is currently stuck at 0.3.4 and not actively supported.
It works fine for now, but there already are some issues, so if you do
decide to start using it for a new project in 2024, prepare to fix some things on your own.

Here's how this thing works:

  • The source repository is open.
  • It's based off Next.js static gen blog starter kit. Tailwind for markup. First time I use either of those. But hey, I have an execute program typescript course sitting for 6 months, and I need to spike on a few typescript things at work anyway.
  • I'm using Obsidian for my notes, and decided to try and use it to write the blog, too. I then ln -s path/to/obsidian/vault/* to the content directory. This should work for any static site generator.
  • Markdown is rendered using contentlayer and it's great.
  • Analytics is on Vercel's side, out of the box.
  • Opengraph images are generated with @vercel/og. This feels like dark magic and I have no idea how it works, but hey, it works. Here's an example for this post:
  • RSS feed is rendered with feed library using a script in scripts/rss.ts, invoked with tsx. Images in the RSS feed are base64-encoded and inlined.


  • Images are generally stored in the content directory, side by side with a post.
    • All .png images are copied over from ./content/**/*.png to ./public/ in a build step by scripts/ That way, both the compiled website, and Obsidian vault can have nice images without too much hassle with paths.

Same Markup, Different Presentations

Over the months, I've changed a few things, and mostly it was fun to hack on. I want most of the Obsidian features to work seamlessly in the notes that I publish. Links, callouts, footnotes, perhaps tables, images. Some of that is now solved, but there are more things on that todo list:

  • Content for pages, posts, and daily notes is generated with `Contentlayer`.
  • There's some additional code that allows for MDX processing of the fields in the front matter of posts.
  • Callouts. Early on, I've had a custom <Callout> component that I've fed to MDX, but that would mean that the note in Obsidian has the Callout block that doesn't actually represent a Markdown callout, or a callout block Obsidian would understand. So I've switched to Obsidian-friendly callout format in this commit
  • TODOs. remark-gfm mostly takes care of that, so I can have todo items with checkboxes in both Obsidian, and in the rendered blog with GitHub-flavored Markdown syntax.
  • Footnotes. I want to be able to have footnotes that render as an aside on desktops, but that show up in the usual footnotes section on smaller screens.
  • Tables. Obsidian 1.5 made a great UI on top of Markdown tables, so you can actually use them. I'd love to use tables in my posts, but that might be tricky in mobile layouts, though.
  • Diagrams. Obsidian supports Mermaid diagrams out of the box, and adding them to the site is relatively straightforward. Tweaking their sizes and color schemes to support light mode and dark mode is a little bit tricky, though.

Content Types

  • Daily notes. I've added daily notes to be able to write and send quick, small notes, and not think twice about them — and they're fun. But now I think it's time to set up the routing, so I can link to one specific daily note.
  • Tags and topics. There's enough content to add topics, and support "native" Obsidian tags.
⌘ ⌘ ⌘
Originally published on Jun 16th 2022.
Last update on Dec 19th 2022.