October 2022 Update: This project is now outdated, and I've integrated thoughts into this site. It follows similar thinking, except structured a bit more maturely.
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.
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,
};
});
}
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.
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>
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.