My next.js static blog setup
2021-12-26
TL;DR src here https://github.com/cmdcolin/cmdcolin.github.io
Update 2023: converted to app directory mode, see https://cmdcolin.github.io/posts/2023-04-08-nextjs-appdir-blog
My personal homepage originally used statocles, a perl-based static site generator (http://preaction.me/statocles/). I didn't really blog using it, just a homepage for myself plus some links to my tumblr blog. But, if I linked people to the tumblr blog directly, it would give people terrible popup ads and trackers. So, I switched to github pages+next.js this year. I considered a number of alternative static site systems, but next.js seemed to hit some nice goals
- Flexible
- React-based (as opposed to template-based like jekyll, eleventy, etc.)
- Markdown driven, and can use MDX (edit 2022: I removed MDX, I disliked the
complicated that it brought. Now all posts are plain markdown, parsed with
remark-gfm
for github flavored markdown, and all pages aretsx
) - RSS feed (bonus)
- Active community
Other systems almost worked and were attempted but aborted
#First and second iterations
The first iteration of my next.js blog
- I put every blog post in the "pages" folder. This worked ok but I had to
manually edit the index.mdx file to have long lists of stuff like this

The second iteration, I wanted to automatically generate a list of recent blogposts from files on disk
-
I used the next.js "blog-template-typescript" example folder from their monorepo.
-
The new blog posts are generated from markdown files in the
_posts
folder, and get rendered by the filepages/posts/[slug].tsx
(yes, the filename includes square brackets). -
getAllPosts in
lib/api.ts
gets a listing of the files in _posts folder, which I can call from thegetStaticProps
method on next.js pages
#Stripping off unnecessary stuff from blog-starter-typescript
The blog-starter-typescript
template has many tiny components, I removed some
of them to make it easier for me to orient myself
#Removing tailwind CSS
The blog-starter-typescript
template uses tailwind CSS and uses "modern web
design" (aka: gigantic "tiles" instead of links, images that are way too large,
etc https://next-blog-starter.vercel.app/)
I started making a more basic design. I tried to roll with the tailwind CSS for a bit, but ended up removing it entirely.
Tailwind CSS is sort of like a CSS-in-JS system, except every CSS attribute is encoded in a CSS classname. For example, here are some tailwind CSS snippets
<div className="container mx-auto px-5"></div>
<footer className="bg-accent-1 border-t border-accent-2"></footer>
<div className="max-w-1xl mx-auto"></div>
<div className="min-h-screen"></div>
<a className="hover:underline"></a>
<h1
className="text-2xl md:text-2xl lg:text-2xl font-bold tracking-tighter leading-tight md:leading-none mb-12 text-center md:text-left"
></h1>
They claim this is better than using external CSS (see comparison here https://tailwindcss.com/docs/utility-first) but it is yet another language to learn, and kind of tricky.
But, the reason I gave up with tailwind is actually because tailwind CSS resets
a lot of HTML styles so things like <h1>
, <h2>
, <ul>
, <li>
, <a>
have
no styling at all. This is done by tailwind preflight
https://tailwindcss.com/docs/preflight (which you can disable, but it is enabled
by default)
Stackoverflow has some ways to help restore styling and keep preflight, but it still struck me as odd. Examples
To me it was surprising the extend that tailwind goes to unstyle the default browser styles, removing "idiomatic HTML" styles, so I removed tailwind for now. Perhaps I'll return to it another time
#Using MDX for blogposts in next.js
(UPDATE 2022) I no longer use MDX in my blog, my blogposts are all plain markdown and pages tsx, but leave this here for reference
In the template from next.js team, the blog-template-typescript
, it uses a
fairly simple lib/markdownToHtml.ts
function right in the
pages/posts/[slug].tsx
file (the markdown is statically pre-rendered in the
true static blog sense, using the getStaticProps function). This is,
unfortunately, over-simplified for the MDX case, because MDX properly needs to
hydrate the components using react on the client side also
To fix, the module https://github.com/hashicorp/next-mdx-remote offers a way to load actual MDX files.
#Adding syntax highlighting the next.js code snippets
(UPDATE 2022) I changed to using plain remark with https://github.com/wooorm/starry-night (UPDATE 2022 v2) I changed from starry-night to rehype-highlight. starry-night did not have good typescript/tsx support
There are a couple results from google about how to add syntax highlighting to next.js but I still found it difficult.
My method ended up a bit different where I manually included the prism JS and CSS from a CDN essentially and it worked
Other methods e.g. adding react-prism in next.config.js (like https://github.com/mikeesto/next-mdx-prism-example does) I think clashed with MDXRemote perhaps, or maybe I was tussling with tailwind CSS too much to make a clear thought out of it, but syntax blocks on my blogposts should now be properly highlighted
#RSS feed
I also followed this great guide to add a RSS file for next.js https://ashleemboyer.com/how-i-added-an-rss-feed-to-my-nextjs-site
Link here, for your feed readers https://cmdcolin.github.io/rss.xml
Not many people may use RSS much anymore, but I do use it (via feedly), and I love music blogs that keep posting on blogspot year after year, and the occasional programming post is nice too