I've jumped around between different methods of creating static websites. Jekyll, Hugo, Gatsby, Sanity, Keystone, Contentful, Wordpress, etc. I can't count how many times I've had to copy paste data from one platform to another only to be disappointed by the features.
When using some sort of rich text markup editor, there's always an issue of parsing. I remember Sanity portable text being a nightmare when it initially released. Although I believe it's gotten much better.
There's a wide flavor of methods for using markdown flavored editors. But I'm going to say something controversial. I don't really like Markdown.
So in the past I've always stored HTML as text on a database and used something like react-html-parser to parse it on the page. Then it's just a matter of using server side rendering to make things SEO friendly.
But that still leaves me with having to build an API. And the last thing I want to do is build a CMS for a site I only maintain for fun. That's way too many forms.
Something like Contentful is nice, it gives you the GUI editors, the storage and the API. But there are tradeoffs. You can't directly embed a YouTube video, for example. You don't get as much control over the structure of your data as you do with your own database. And of course there's the matter of what if I want to switch to something new? Can't exactly transfer that data to the next thing, can I?
Today I've finally thought of a solution. HTML. Not storing it, just writing it, and writing it directly into my code. I know, sounds horrible, so many things wrong with that right? But I thought I'd give it a go. Here's what I've come up with so far and why I think it may be more viable than it sounds.
First I set up TypeScript classes as “Models” to represent my data, I even created a singleton to represent me as an author:
With the models set up I can create an object dictionary with a slug as a key and metadata as the value. For reference I created an enum to represent the slug. This helps me keep slugs unique and gives me a short reference to each one.
From there, all I had to do was recreate a layout that accepts the slug as a prop and start writing the content as a child component.
As to the question of how to get all blogs for the home page, it's as simple as using Object.getOwnPropertyNames on that enum I created before:
That's it, Emmet means I don't really have to write much HTML and ESLint/Prettier keeps me from having to deal with long lines. It's really not much extra effort than typing into an editor. Plus, I don't have to worry about weird markup languages, video support or dealing with an API. Just add a new blog object with some metadata, create a file with NextJS file based routing, and start typing. I can even use hot reload to see how my content looks on the page. For static content, I can just write static content. I don't know why I didn't think of this before.
When I first built my site in React it was exciting, and with every new tool I did a rewrite, that was fun. But now I want to move on to different kinds of projects. And I'd like to talk about them here. What I don't want to do is have to worry about not having a CMS or needing to move to new tools. I just want to be able to host on Vercel and move on.
I'll be migrating all of my previous posts over to this format. Which realistically won't take nearly as long as it took to move it from Sanity to my own database. I'll shut down the Digital Ocean DB, close the Hasura account, stop trying to figure out how to generate GraphQL types from generated Prisma schema (way harder than it sounds) and move on to learning new stuff. I know React, I know API's, I know SEO and building content sites. I don't want to be spending much time on those things. But I'm glad I'll get to keep the content flowing.