EkomEnyong.com
Published on
4 min read

Rebuilding My Blog with Next.js, TypeScript, and Contentlayer

I updated my Next.js, TypeScript, Tailwind CSS blog with a fresh coat of paint, new components, and Contentlayer for markdown.


Author

Table of Contents

Introduction

It's that time of year again when I totally redesign my website from the ground up. While my individual post template hasn't changed too much, I redesigned my page templates to feel a little more me. I have some future plans and wanted to align my personal website design with those upcoming plans.

Not much else has changed in this website refresh. I did add a few new custom components and features but I'm still using Next.js, TypeScript, and Tailwind CSS. Beyond the design of the site, the only other major change is one you can't see — a new tool to compile my markdown files.

Let's take a break look at how I changed my website this time around.

Contentlayer for MDX

Screenshot of Contentlayer (contentlayer.dev)
Contentlayer is now in beta!

Last year was the first time I built a blog website using MDX using @next/mdx. In January of this year, I came across Contentlayer, a content SDK that focuses on great DX and performance. Some of the reasons you might love Contentlayer include:

  • Easily import your content as data
  • Use JS/TS — no new query language to learn
  • Strong-typed data with auto-generated type definitions
  • Built-in and configurable content validations
  • Detailed error messages
  • Fast build and page performance

The first tool I used that also follows the concept of structured content, or thinking of content as data, was Sanity.io, which I enjoy using to build web platforms for clients. Discovering Contentlayer was perfect to use for projects that need scalable content but don't need a robust CMS. Now that it is in beta, I suggest you try it out on your next project.

Fresh Coat of Paint

Macbook, iPad, and iPhone mockups of EkomEnyong.com homepage.
A modern and minimal design with pastel backgrounds.

While I appreciated how clean my previous design was, I wanted something that didn't feel like every other portfolio website out there. I decided to go with large sans-serif typography on pastel colored backgrounds. It's a refreshed, modern take on minimal and I am actually really proud of this design.

New Custom Components

I added a sticky, collapsible TableOfContents component that makes the reading experience for desktop users much more enjoyable. I also added a SocialShare widget to make it easy for readers to share my posts with their audiences on Twitter, FaceBook, and LinkedIn.

Admonition

I love using admonitions in Obsidian and I wanted to bring that same feel to my blogging experience. I have created 10 different admonition types with an optional title prop and the ability to nest admonitions. Check out some of them below:

info

This is an example of a default admonition without a title prop. In this case, the title default to the type of admonition.

I edited the title here!

This is a cool message!

nested admonitions, anyone?

This is another cool message!

warning

I know... nested admonitions are 🔥!

Upgraded Code Blocks

I upgraded my code blocks to include code titles, line number functionality, and line highting with rehype-prism-plus. I have also included a Pre component that allows a user to copy a code block to their clipboard. Try it out by hovering over the code block below.

project/file-path.tsx
// You can copy this code block
interface EmojiProps {
  label?: string;
  emoji: string;
}
// Note the highlighted rows below
export default function Emoji({ label, emoji, ...props }: EmojiProps) {
  return (
    <span
      role="img"
      aria-label={label || ''}
      aria-hidden={label ? 'false' : 'true'}
      {...props}
    >
      {emoji}
    </span>
  );
}

TAGS

#next.js
#mdx
#tailwind css
#typescript
#contentlayer