How do I manage this blog's content remotely?
In this post, I will break down the workflow I use to manage this blog's content remotely, why I overengineered an overthought-underused blog (that was a lot of words), and finally, how I was able to (almost) achieve the near-perfect setup I wanted.
BLUF:
Here's the source code for the "plugin" that allows to use Git as a source for Contentlayer. It will clone and sync the content to your machine. (If your content is in a private repo, you'll need to set up a personal access token).
So... I guess I'll need to make my point first. Let's start by:
#Why did I choose to go this way?
Last year, I got myself thinking multiple times about a better way to manage the content I create. I always loved to write, and for that, I had already tried Medium (please don't), and LinkedIn, but those still don't feel like the places I want to have my content. And that leads us to a quick tangent:
#Blogging platforms
There is inherit problem with blogging platforms, and that is that they are built for thousands of users, for the plans of the company, for every topic ever, and this makes them lose focus, getting bloated and filled with useless content and features.
Medium turned into a paywalled platform that blocks out users from content created by other users, and LinkedIn is still a social network, a weird one and a Microsoft one.
#The plan
- I wanted somewhere where I'd have the freedom to do whatever I wanted with it. I may want a code block or an interactive section to explain something, and so on.
- I wanted to be able to use my content in any way and not be locked into a platform.
After that, I decided to give my website a (more than needed) facelift. So to start on this ongoing task (for the last whole year), I decided to sit down and list my options:
-
Framework:
-
Next.js - I was already using it for my website, and it's my favorite framework for React, so it was a no-brainer. (Though I did consider Astro for a while.)
-
Content Management:
-
Notion - I did use Notion for a while, and it's a great tool, but my minimalistic side hates bloating on everyday software, and Notion got to the point where I was finding myself spending more time setting up my workspace than actually doing the things I needed to.
-
On the code itself1 - I did consider this with MDX for a while; it is as simple as it gets on Next.js, it will always be in sync with the code, and I could use any tool I want to write my content. But this still made my content "local". My website only had the content, and I wanted to be able to use it anywhere I wanted.
-
Git - I
lovealready use Git every day, so why not use it to manage my content? I could use it to manage my content and then sync it to my website and anywhere else I wanted to.
-
Content:
-
MD - I love markdown; it's simple and easy to use, but... it can make you transfer a lot of the work to the code, adding and appending to the website code to add new features, and that's not what I wanted.
-
MDX - It's markdown, but with the ability to add React components to it, it seems like a perfect fit for what I wanted... Oh boy, I had no idea what I was getting myself into.
And with all that set, we go to the next step:
#How do you glue it all together?
I had already decided on the tools I wanted to use, but I still needed to figure out how to make them work together, and that's where Contentlayer came in.
Contentlayer is a tool that allows you to use your content as data, and it's a perfect fit for what I wanted; it has a great integration with Next.js, and it's pretty simple to use, but it had a problem. Let's look at the supported content sources:
Well, that's not what I wanted; I wanted to use Git, and I wanted to use MDX, and I wanted to use them together, so...
Contentlayer has a way to add new content sources, and a file-based one. This sparked an idea of how to make it work. I could use Git to manage my content, then use Contentlayer to read it, and then use it on my website.
NOTE:
Just to clarify the next section, this is not a tutorial on how to use Contentlayer. If you want to learn how to use Contentlayer, I recommend you check their (beautiful) docs.
#All of that said, let's see how it works:
IMPORTANT:
The code in this next section is a simplified version of the code I use on my website; this makes it easier to understand, but it's not the actual code I use. The whole thing is linked below.
The code is here and can be used as a custom syncFiles
function on the makeSource
call, starting from the basics:
- How can we clone a git repository in Node.js?
promisify
is a "node:util" function that converts a callback-based function to a promise-based one. This is a hacky way to asynchronously execute shell commands.
And now for the actual syncFiles
function:
And is that it? Well, pretty much, it ends up that Contentlayer has an awesome API that allows you to extend and customize it in any way you want. Now, for the last step, how do we use it?
And that's it. Now you can use Git to manage your content and Contentlayer to process it, so you can use it on your website. As I said for the Contentlayer setup, there are some more steps, but I'll leave that for you to check on their docs.
#Final thoughts
I'm really happy with the setup I have now. I can use Git to manage my content and Contentlayer to process it; I can use it on my website; and I can use it to do anything from discovering the most used words on my blog to training an ML model to substitute me on my time off.
But as with anything in life, there are some downsides. The biggest one is that I need to push
my content manually. This is not a big deal, but it's something I need to remember to do, and I'm not a big fan of that. I'm pretty sure Obsidian can help me with that since it can use a repo as the source, but I haven't tried it yet.
Other than that, only the CI/CD integration on Vercel is something that works flawlessly with the website, but the contents are not on the same repo, so I need to manually trigger the build, and I know there are ways to automate that, even with GitHub Actions (I think), which is something I'll look into in the future.
And I think that's it. I hope you enjoyed this post, and if you have any questions, feel free to reach out to me on X or LinkedIn 👀.
#Footnotes
-
This was my choice for a while, and I still like it the most. It is simple, fast, and reliable, but as we discussed before, there are some issues, and in this case, the content gets even more intertwined with the code. Next.js uses the MDX files as the pages following a
Layout.tsx
file; this is awesome for simplicity but not so much for flexibility. Any new section I wanted to add, like a TOC (summary), was already out of scope. ↩