thoughts

The motivation for thoughts came from wanting a centralised space to be able to store small posts on things I had been thinking about and anything else I had been exploring — mainly to do with writing code, but I decided to leave it open-ended in case I wanted to talk about another hobby like photography or design.

This was a fairly straightforward project thanks to the efficiency of the Next.js framework and how well it can work with Markdown files.

Next.js with MDX

Each post is stored in an mdx file: a Markdown file that allows JSX to be written inside. This allows me to import and use React components from within Markdown, in the event that I want to add something like a custom button. I'm not currently using any JSX in them but I thought it would be good to implement now so I can take advantage of it in the future if I decide to.

These Markdown files are used in conjunction with Next.js' dynamic routing. Using getStaticProps, which gives access to files as objects of data:

export function getStaticProps() {
  const apps = getApps();
  return { props: { apps } };
}

export function getApps() {
  const appsPath = join(process.cwd(), "content");

  const appFilePaths = fs
    .readdirSync(appsPath)
    .filter((path) => /\.mdx?$/.test(path));

  return appFilePaths.map((filePath) => {
    const source = fs.readFileSync(join(appsPath, filePath));
    const { content, data } = matter(source);

    return {
      content,
      data,
      filePath,
    };
  });
}

gray-matter

As shown above, I used gray-matter to add metadata functionality to the Markdown. This can be added at the beginning of a .mdx file like so:

---
title: Hello
description: Hello World!
---

With gray-matter, these fields can be accessed like an object using app.data.title and app.data.description, which are used to populate the components.

react-markdown

To convert the markdown to HTML elements, I used react-markdown. The implementation was as simple as surrounding my content in a ReactMarkdown element tag (with some custom props) like so:

<ReactMarkdown remarkPlugins={[gfm]} components={CodeBlock}>
  {app.content}
</ReactMarkdown>

Tailwind

Like most of my recent projects, I used Tailwind for styling. In particular, I used Tailwind Typography to style the posts to make things easier, because for a small project it didn't make much sense to spend a lot of time deciding on spacing and font sizing when I could use this instead. However, I'm not a fan of the way Tailwind Typography styles code blocks - they don't have highlighting and it's a little ugly in light mode. For this, I used react-syntax-highlighter so that I could write my own CodeBlock component, using prism.js themes.


With thoughts I wanted something minimal and simple, without spending too much time building it. I used it as a nice break away from other projects and work I've been doing, and it felt pretty rewarding despite not being all that challenging.